Angular Post Request Cors issue - c#

I got CORS issue when I am trying to make post request to c# web api.
Below is the error:
Access to XMLHttpRequest at 'api url in different domain' from origin
'client url' has been blocked by CORS policy: Response to preflight
request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
The same API call with GET request is working.
Both sites are deployed with windows authentication enabled.
I am using Angular io, 1.7.** with typescript. Below is how I call the api with post request in typescript.
let httpHeader = new HttpHeaders();
httpHeader = httpHeader.set('Content-Type', 'application/json');
this.http.post(this.apiUrl, this.bodyObject,
{
headers: httpHeader,
withCredentials:true
}).pipe(map(response => {
return response;
})).subscribe(result => {
console.log(result);
}, function (err) {
console.log(err);
});
I first thought that it might be api cors issue and tested with below jquery code and it is working.
<script>
$.ajax({
url:apiUrl,
type: 'post',
data: {
serviceName: "Country"
},
xhrFields: {
withCredentials: true
},
dataType: 'json',
success: function (data) {
console.info(data);
},
error: function (err) {
console.error(err);
}
});
</script>
So I think, I have something to do with my angular code. Can you guy highlight me what could be the issue.

try to add this in $.ajax
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type':'application/json'
},
crossDomain: true,

Related

How to pass bearer token into request header

It's my first time building a web api. I've successfully set up the model view controller and enabled token generation. However, I am stuck on how to pass the access token through the request header. After I have logged in and attempt to view another page, there is nothing in the header in regards to the authorization therefore I receive a 401 error. I've looked at several blogs, forums and articles over the past couple days and cannot come to a conclusion on how this is done. I have my jquery storing the header in a variable, but I am unsure on where that is stored and how to reference it or where to put the reference. I've messed around with setting it in global.asax and some of the config files, also at the top of the controller class. My next thought is to create a web page for each controller and storing the authorization there, even still I don't know how to dynamically place a token that would vary for other users. I feel like there is something very simple that I'm missing. I suppose my question is how do I store my javascript variable in each request header? Here is my javascript for reference:
$("#btnLogin").on('click', function () {
//var data = { Email: $("#loginEmail").val().trim(), Password: $("#textPwd").val().trim(), ConfirmPassword: $("#loginPwd").val().trim() };
$.ajax(
{
url: "/TOKEN",
type: "POST",
data: $.param({ grant_type: 'password', username: $("#loginEmail").val(), password: $("#loginPwd").val() }),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
success: function (resp) {
sessionStorage.setItem('userName', resp.userName);
sessionStorage.setItem('accessToken', resp.access_token);
var authHeaders = {};
authHeaders.Authorization = 'Bearer ' + resp.access_token;
$.ajax({
url: "https://localhost:44327/api/values",
type: "GET",
headers: authHeaders,
success: function (response) {
$("#loginEmail").val(),
$("#loginPwd").val(),
$("#msg").text(response)
}
});
},
error: function () {
$("#msg").text("Authentication failed");
}
})
});

I am using Window.onpopstate method in ajax for SPA

I am using Window.onpopstate method in ajax for SPA, before that I used window.history but I got an error like
"jquery-1.10.2.js:8720 Failed to load location:
http://localhost:22102/Coach/AddCoaches, state:
{"url":"/Coach/AddCoaches"}: Cross origin requests are only supported
for protocol schemes: http, data, chrome, chrome-extension, https."
my ajax call is
<script>
$('#loadingImage').hide();
$('.jq-navigation-link').click(function () {
var url = $(this).data('url');
loadPartial(url)
})
function loadPartial(url)
{
$('#renderPartial').html("");
$('#loadingImage').show();
$.ajax({
url: url + "?ispartial=" + true,
type: "GET",
success: function (data) {
$('#loadingImage').hide();
$('#renderPartial').html(data);
}
})
window.history.pushState({ url: url }, '', url);
}
window.onpopstate = function (event) {
debugger
if (event.state) {
var url = "location: " + document.location + ", state: " + JSON.stringify(event.state);
load(url);
}
};
</script>
<script type="text/javascript">
$('body').delegate(".btnUrl", "click", function (e) {
e.preventDefault();
var url = $('.btnUrl').data('url');
//var test = $('.form').serialize();
$('#loadingImage').show();
$.ajax({
async: true,
url: url,
type: 'POST',
data: $('.form').serialize(),
dataType: "json",
success: function (data) {
if (data.Success) {
$('#loadingImage').hide();
loadPartial(data.Url);
}
else {
$('#loadingImage').hide();
loadPartial(data.Url);
}
}
})
})
function load(url) {
$('#renderPartial').html("");
$('#loadingImage').show();
$.ajax({
url: url,
type: "GET",
success: function (data) {
$('#loadingImage').hide();
$('#renderPartial').html(data);
}
})
}
</script>
Error clearly says it is Cross origin requests. Your Web application is using port 8720 and you web API is using port 22102. Browser is considering requests as different origin and for security reason is blocking data for another site request.
For resolving this, you need to enable CORS on your application OR need to host Web application & Web API at same port or same IIS application.
For Enabling cors try:
install nuget package:
Install-Package Microsoft.AspNet.WebApi.Cors
In App_Start/WebApiConfig.cs, add following code in Register method before map routing :
config.EnableCors();
In API Controller, [EnableCors] attribute to the class:
[EnableCors(origins: "http://yoursitehere", headers: "*", methods: "*")]
public class TestController : ApiController
{
// Controller methods not shown...
}
OR
Adding the header through web.config
<httpProtocol>
<customHeaders>
<clear />
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
For more details refer:
https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
https://forums.asp.net/post/5795304.aspx

How To Do CRUD Operations in WEBAPI in asp.net using AJAX

I would like to perform CRUD Operations on WEB API in asp.net using AJAX JQuery.I am very new to web api
The Following Code can be used to hit a web api with a GET Request
var url1 = 'http://api.com/customer/1234';
$.ajax({
url: url1,
type: 'GET',
headers: {
'customHeader': 'Value',
'customHeader2': 'Value2'
},
success: function (data) {
alert('Success');
}
});

Calling ServiceStack Service Cross-Domain with Cors Issue

I am in the process of testing some web services on my local machine. Because the test page sits on the root at port 80, and the web-services on different ports, I get the following error from Chrome's diagnostic tool:
XMLHttpRequest cannot load http://PCNAME:8083/PackageSearch. Origin http://PCNAME is not allowed by Access-Control-Allow-Origin.
After doing some searching, I came across the CORS Features of ServiceStack, and put the following attribute on my Web Service:
[EnableCors(allowedMethods: "GET, POST")]
However, the error still persists. This is the ajax call:
function packageSearch(tourCode) {
var searchUrl = url + 'PackageSearch';
var searchData = {
TourCode: tourCode,
};
$.ajax(searchUrl,{
data : JSON.stringify(searchData),
type: 'POST',
contentType: 'application/json, charset=utf-8',
dataType: 'json',
success: function (result) {
oTable.fnClearTable();
}});
};
Where url is http://PCNAME/.
EDIT
I have even set up the following during the Configuration stage:
public override void Configure(Funq.Container container)
{
Plugins.Add(new CorsFeature());
RequestFilters.Add((httpReq, httpRes, requestDto) =>
{
if (httpReq.HttpMethod == "OPTIONS")
httpRes.End();
});
base.SetConfig(new EndpointHostConfig
{
DefaultContentType = "application/json",
GlobalResponseHeaders = {
{ "Access-Control-Allow-Origin", "*" },
{ "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" },
{ "Access-Control-Allow-Headers", "Content-Type, origin, accept" },
}
});
});
} // Configure
You need a ContentType specified and may have to do a preflight message (OPTIONS) to do the handshake that will allow you to proceed with a cross domain call.
I thought this code looks suspicious:
if (httpReq.HttpMethod == "OPTIONS")
httpRes.End();
I think although you are setting all header responses to send CORS headers, you may be short-circuiting the HTTP response headers - they never get sent. You could verify if you use Fiddler to check the exact http response headers sent back.
See this SO answer: ServiceStack returns 405 on OPTIONS request
They send the headers before calling httprequest.end().
You probably have to do:
httpRes.AddHeader("Access-Control-Allow-Origin", "*");
... before calling response.end()

Null parameters doing HTTP POST from Ajax to Web API

I've read several StackOverflow posts about this and corrected my code several times
but I cant get my webAPI post method to work. I'm trying to receive a post parameter
but it comes always null.
What I am trying to do is receiving a base64 string that represents a canvas that is
creating with jquery when the user clicks the button:
function MakePhoto(ctrl) {
html2canvas(ctrl, {
onrendered: function (canvas) {
var canvasData = canvas.toDataURL()
jQuery.ajax({
url: "../api/webinfo",
type: "POST",
data: { imagedata: canvasData },
success: function () {
alert("success");
},
error: function () {
alert("failure");
}
});
}
});
}
my WebInfoController.cs looks like this:
public void Post([FromBody]string imagedata)
{
}
imagedata parameter comes always NULL
And this are the headers I am receiving at webapi:
"Method: POST,
RequestUri: 'http://myhost/RestFulApi/api/webinfo'
Content: System.Net.Http.StreamContent
User-Agent: Chrome/27.0.1453.94
Content-Length: 42226
Content-Type: application/x-www-form-urlencoded; charset=UTF-8}
I hope you could help me.
Thanks
OK, I found the problem after some hours researching. I had to pass the data parameter to ajax function using:
"=" + canvasdata, without the parameter name:
jQuery.ajax({
url: "../api/webinfo",
type: "POST",
data: "=" + canvasData,
success: function (response) {
alert(response);
},
error: function (response) {
alert(response.responseText);
}
});

Categories