CORS error with AngularJS post only in FireFox - angularjs

I am having issues only with FireFox when making a cross origin request in an Ionic app (so it's using AngularJS). The js app is doing a $http.post() to a Laravel 5.1 API, and I get the following error only in FireFox (39.0.3):
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://blah.dev/endpoint. (Reason: missing token 'content-type' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel).
This is on my localhost (OSX Mavericks). and works fine in Chrome and Safari, only FireFox is given the error. I have cleared the cache, and tried in a "private window", with the same results.
Here is the Laravel route defined to handle the OPTIONS request:
Route::options('endpoint', function() {
return response('OK')
->header('Access-Control-Allow-Headers ', 'Origin, Authorization, X-Requested-With, Content-Type, Accept')
->header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
->header('Access-Control-Allow-Origin', '*')
->header('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0')
;
});
Route::post('endpoint', array('uses' => '\Path\To\Controller#endpoint'));
I did find this question that seems to have a similar issue only in FireFox, but the solution was to comma separate the Allow-Methods, which I already am.

The message " missing token 'content-type' " is about the client. For a http request to be a valid post one, it must have a header
'Content-Type': 'application/x-www-form-urlencoded'
or
'Content-Type': 'multipart/form-data'
The first content-type is the most common one.
In angularjs one way to do a CORS post request is
$http.post(
'http://external-domain.ext/the/rest/url',
'param_name=param_value',
{headers:{'Content-Type': 'application/x-www-form-urlencoded'}}
).
then(function successCallback(response) {
$scope.something = response;
}, function errorCallback(response) {
// not good
});
If the server is configured with
header('Access-Control-Allow-Origin', '*'), the CORS post must succeed without authentication and credentials.

on the back end try putting
->header('Access-Control-Allow-Credentials', 'true')
and on the front end try putting
.config(function($locationProvider, $httpProvider) {
// CORS requests with credentials
$httpProvider.defaults.withCredentials = true;
})

Related

CORS request, Content-Type: application/json

I am working on a web app with a React front end and a node back end. They are both running on my local computer, on localhost:3000 and localhost:8080 respectively. Is it possible to make a CORS request using headers: { "Content-Type": "application/json" }? Based on looking at other questions it seems to be, but I am still getting the error in the console:
Access to fetch at 'http://localhost:8080/chordSheets/0' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
My code is:
React Component
fetch(`http://localhost:8080/chordSheets/${id}`, {
method: 'POST',
credentials: 'include',
mode: 'cors',
body: data,
headers: {
"Content-Type": "application/json",
},
})
Node settings:
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", 'http://localhost:3000');
res.header("Access-Control-Allow-Credentials", true);
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Options");
res.header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
req.login = promisify(req.login, req);
next();
});
If I understand things correctly this should allow the CORS request with "Content-Type": "application/json" I don't understand why the console error is saying The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when it is set to localhost:3000.
Thanks in advance.
This error is triggered by the browser. Cannot be fixed by tweaking client app code. To fix this you have to get your node server to handle the OPTIONS preflight request which is trigged by the browser when you make an ajax request to a different origin than the webpage is currently running on.
The server then needs to respond to this with the correct headers:
Access-Control-Allow-Origin: '*' or 'Access-Control-Allow-Origin': 'http://localhost:3000'
You can add this package to your node server: https://expressjs.com/en/resources/middleware/cors.html
This will do all the heavy lifting for you.
If it just for development purposes you can just run chrome with web security disabled:
Mac: open -a Google\ Chrome --args --disable-web-security --user-data-dir=""
Windows: chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security

IE Edge Angular JS $http post CORS request JSON not working

I am working on Angular JS app which connects to CORS .NET WEB API. The below code works fine with chrome / firefox / safari browsers but for some reason not on IE Edge (any version). I get OPTIONS pre-flight response with HTTP code 200 but subsequent post request does NOT fire.
var postData = {
'id': 1,
'name':'Niket'
}
function SendData(APIServiceUrl, postData)
{
return $http({
method: 'POST',
url: URL + APIServiceUrl,
data: postData,
headers: { 'Content-Type': 'application/json; charset=UTF-8' }
});
}
If I switch the content-type to
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
then I do get the post request working. But our API Server response only allows
Access-Control-Allow-Headers: Authorization, Content-Type
I have gone through dozens sites to solve this issue, and have tried bunch of solutions ranging from JSON.stringify(), verifying caching is disabled, syntax checking, CORS setup etc. but not able to find solution to why the POST request does NOT fire in IE Edge.
An article that I have found along similar line is this but that has not been SOLVED either --> Post JSON ajax request with cors not working in IE10/Edge.
Angular JS ver 1.5.7, IE Edge version 40.15063.0.0,
PLEASE HELP!!!

CORS Issue in Web Console (angular js)

I have a developed a web console in angular JS in which I am using post and put methods and making HTTP requests in which I send json and calling a WSO2 REST API to get response accordingly. Its running on server but I am facing CORS problem. I have add add extension in browser and enable it otherwise I get following error.
XMLHttpRequest cannot load http://127.197.200.100:8000/ManagementAPI/createuser. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.197.200.100:8000' is therefore not allowed access.
This is how I am sending request
CreateUser: function(adata) {
var config = {
headers :{
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}
var promise = $http.post(213.187.243.177:8283/ManagementAPI/createuser,adata,config).then(function (response) {
return [response.status,response.data];
},function (response) {
console.log("Error Returned" + response.status);
return [response.status,response.data];
});
return promise;
},
I have tried ThisLink for solution but did not work. Need a solution for accessing it without CORS.
Set headers in back end for avoiding CORS issues .
Sample code in php is shown in below
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400'); // cache for 1 day
}
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
exit(0);
}

Ionic http post to external url

Im trying to send a post to a url with Ionic using angular, but i have the response:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access. The response had HTTP status code 404.
I know that the external service is working, because i tested it by ajax and everything works perfectly...
Below the code used in AngularJS (Ionic) and Ajax:
Ionic:
var loginServiceUrl = 'http://url.com.br'; //It is not the real one
var loginServiceData = {
email: email#email.com.br
senha: 1234
};
$http.post(loginServiceUrl, loginServiceData).
then(function (res){
console.log(res);
});
Ajax:
$.ajax({
type: "POST",
url : 'http://url.com.br', //It is not the real one
data : {email: 'email#email.com.br', senha: '1234'},
success: function(result) {
$('html').text(JSON.stringify(result));
}
});
Does anyone know why I get the post via ajax on my localhost and not with the ionic, also localhost?
Check this out. It is well explained how to handle issues like yours --> http://blog.ionic.io/handling-cors-issues-in-ionic/
Try to add headers in your POST request.
//example of DataToSend
var DataToSend = {
userID: deviceID,
coordLat : pos.coords.latitude,
coordLon: pos.coords.longitude
};
$http({
method: 'POST',
url: 'http://url.com.br',
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
data: DataToSend
})
CORS has nothing to do with your frontend.
Before sending the POST request, browser send a OPTIONS request to the server to check if call from your domain is allowed or not.
Since, you are getting Status 404, that means your server is not handling the OPTIONS request
1. Allow the OPTIONS request (same as POST)
Now come to second part i.e " Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' "
After allowing the OPTIONS request, now set the response header of OPTIONS request (Browser will check the response of OPTIONS request and then process the POST request only if there is 'Access-Control-Allow-Origin' present in the OPTIONS response.
2. Set the response headers of OPTIONS request
response().setHeader("Access-Control-Allow-Origin", "*");
response().setHeader("Allow", "*");
response().setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS");
response().setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent");
Example..
(In Java)
Router:
OPTIONS /*all
controllers.Application.preflight(all)
Controller Function:
public static Result preflight(String all) {
response().setHeader("Access-Control-Allow-Origin", "*");
response().setHeader("Allow", "*");
response().setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS");
response().setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent, Auth-Token");
return ok();
}
Hope this will solve your problem.
Cheers

AngularJS $http GET method to backend server: Request Method:OPTIONS 405

$http GET request to a clojure backend, to get a list of services.
I get is an OPTIONS request (???), which gets a 405 response...
<code>
var config = {headers: {
'Authorization': 'Bearer d2VudHdvYW5nZV9tZQ',
"X-Testing" : "testing"
}
};
$http.get(SERVER.MESSAGE_SERVICES, config)
.success(function(successCallback) {
$scope.services = successCallback;
})
.error(function(errorCallback) {
console.log(errorCallback.toString);
}).
finally(function() {
console.log("Message services rest call");
});
</code>
**clojure backend**:
<code>
headers {"Access-Control-Allow-Origin" "*"
"Access-Control-Allow-Headers" "X-Requested-With, Origin,Content-Type, Accept"
"Access-Control-Allow-Methods" "GET, POST, OPTIONS"}
</code>
There is no problem that AngularJS sends an OPTIONS request, that is because CORS standards force to do so. Be sure that the server is configured to allow a GET method.
Yes as raso suggested this problem is because of Cross Origin Resource Sharing(CORS). The same old privacy policy prevents JS/ angularJS from making requests across domain boundaries.
Configure server to allow cross domain requests.
Or
If you are using Chrome than you can use this extension to surpass this problem.

Resources