Getting CORS blocked even after ("Access-Control-Allow-Origin", "*") - ajax

I am getting CORS blocked regardless of what I allow. It only yells at me for my POST route, my GET routes it allows just fine. I consistently get
Access to XMLHttpRequest at 'https://simple-startup-survey-backend.herokuapp.com/client_answers' from origin 'http://simple-startup-survey.surge.sh' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I am using an AJAX to communicate with an EXPRESS server. I allow all requests with the wildcard operator. I have tried sending {crossDomain: true} with my request.
//This is my backend in app.js
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,POST,DELETE,PATCH,PUT");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// This is my front end AXIOS call POST request. This is what is //triggering the CORS block
storedData = storedData.concat(storedData2)
axios.post('https://simple-startup-survey-backend.herokuapp.com/client_answers', {crossDomain:true}, storedData,)
.then(function(response){
console.log(response.data , ' save success')
localStorage.setItem("storedData", JSON.stringify(storedData))
window.location.href = "../AnalysisPage/analysis.html";
}).catch()
})
// This is my perfectly functional GET request. It does a bunch of //stuff after this in the .then, but I don't think that is relevant to //this issue
function getgeneralQuestions(){
axios.get('https://simple-startup-survey-backend.herokuapp.com/questions/balanceSheet')
.then(function (response) {
Every damn Google search result on the planet says that what I have in regards to my back end should work. I am using vanilla JS, no JQUERY.
Any help greatly appreciated!
back end Github: https://github.com/TuckerNemcek/SimpleSurveyBackend
front end Github: https://github.com/TuckerNemcek/SimpleStartupSurveyProject

I am running into a similar issue.
My hunch is that surge.sh does not have cors enabled on its server.
My website is actually making the request correctly.
Afterward there is an error and the data is not shown.
Edit: Solved - - - -
Actually, just solved this for myself!
This is my script for publishing.
yarn build; cp build/index.html build/200.html; echo '*' > build/CORS; surge build appname.surge.sh
here is an article about enabling cors for surge.sh https://github.com/surge-sh/example-cors
Also when making changes make sure you are in a new incognito tab each time or go to the network tab on dev tools and Disable cache otherwise your app might be lying to you and thing cors is not enabled when it in fact is enabled.

Related

How to configure OPTIONS request in CORS to Access-Control-Allow-Origin with ASP.NET Web API

I'm having an issue trying to get a token from my server on an Angular 5 project. My POST request is never sent and the server returns 400 Bad Request and shows the following in the console:
My understanding is that I need to configure the OPTIONS request in CORS to allow the cross-origin request, but I feel like I've tried every solution there is out there without any success.
As far as what I have tried so far, in my Web.config I have this:
And I enabled CORS globally in my WebApiConfig.cs:
I even implemented the solution suggested at https://www.stevefenton.co.uk/2012/11/using-cors-with-asp-net-web-api/
Here is the call I am making in my Angular 5 project:
userAuthentication(userDetails: LoginUser): Observable<LoginUser> {
var data = "username=" + userDetails.username + "&password=" + userDetails.password + "&grant_type=password";
var reqHeader = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded', 'No-Auth': 'True' });
return this.http.post<LoginUser>(this._baseUrl + 'Token', data, { headers: reqHeader })
.pipe(
catchError(this.handleError)
)
}
When I make the call using POSTMAN, everything runs smoothly and I get my access_token.
I've managed to resolve this issue. I needed to add Microsoft.Owin.Cors with Microsoft.AspNet.Cors and Microsoft.AspNet.WebApi.Cors.
I then had to add app.UseCors(CorsOptions.AllowAll); to my Startup.cs file:
…and remove the customHeaders from between the system.webserver tags in Web.config:
All is running smoothly now.
Note: It's important to note that when enabling CORS on your WebApiConfig.cs, if you have followed the previous steps I have shown, you must enable it like this:
…and not like this:
If you do, you will get an error stating your header contains multiple values and therefore will deny your Origin access.

SignalR responses overwriting headers

I've built a simple SignalR hub that lives within a WebAPI service, I've included all the required CORS attributes on both WebAPI and SignalR. My WebAPI endpoints are all working as expected but SignalR isn't.
I've tried all I can think of and all I can find online but nothing works, I already tried this answer, and this other to no solution.
My SignalR extension method looks like this
public static IAppBuilder UseSignalrNotificationService(this IAppBuilder app)
{
var config = new HubConfiguration();
config.Resolver = new HubDependencyResolver();
config.EnableDetailedErrors = true;
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR(config);
return app;
}
And I even tried adding the response headers on all requests using the Web.config but I allways get the same error:
XMLHttpRequest cannot load https://MyApplicationServer/notifications/signalr/negotiate?clientProtocol=1.5&access_token=&connectionData=. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'MyOriginService' is therefore not allowed access. The credentials mode of an XMLHttpRequest is controlled by the withCredentials attribute.
After more research and fiddling with the server side of the problem, I ran into this answer and found the error to be with the client side of the request. according to this GitHub issue, the "withCredentials" parameter of the request is always set to 'true'. The solution was to call on the client the start method as follows:
$.connection.hub.start({ withCredentials: false }).done(function () { //... }
Are you changing the request somewhere with some kind of global interceptor? For some reason, the XMLHttpRequest starts with withCredentials:true and this is forbidden when the Access-Control-Allow-Origin is set to *.
What about setting the 'Access-Control-Allow-Origin' to 'http://MyApplicationServer'? It's safer than * and will remove your problem at source.

Ajax in Phonegap not working

I know this question has been address many times on Stack Overflow, but none of the solutions are working for me.
I can't get ANY ajax requests to complete within my phonegap application when running on the device (Android 4.4.2), yet everything works fine from desktop browsers.
First I tried AngularJS $http
Then I tried jQuery .get
Then I tried raw xhr
In all cases, the request immediately fails with no response. I've tried requesting data from my own servers, and from google servers, and elsewhere, all the same. I've tried whitelisting my domains in config.xml, in many forms, still no effect. I've even opened the console, and manually created an XHR and tried to GET on it, and the same thing happens. The request immediately fails. If anyone can please help me out, that would be great. I'm on the latest version of pretty much all my software, having set up my dev environment just today.
Cross domain request headaches. The browser allows the cross domain request but phonegap on the device kills it. I've been there and it took some work getting used to dealing with it. Try using jquery and jsonp in an ajax get request.
Try adding <access origin="*" /> to your config.xml for testing.
Here's an example of an jquery ajax request taken from working code.
$.ajax({
timeout: 5000,
url: 'https://yourdomain.com/yourfile.php',
dataType: "jsonp",
jsonpCallback: 'yourcallbackfunction',
type: "GET",
crossDomain: true,
data: {'somedata':'your data string'},
error: function(xhrObj,text,errorObj){
if(xhrObj.status !== 200) {
var errorTxt='Error Log: ';
errorTxt=errorTxt+"Error code specific:'"+xhrObj.status+"'\n";
errorTxt=errorTxt+"Error status specific:'"+xhrObj.statusText+"'\n";
errorTxt=errorTxt+"Error code general:'"+text+"'\n";
errorTxt=errorTxt+"Error status general:'"+errorObj.message+"'\n";
console.log(errorTxt);
}
}
});
function yourcallbackfunction(data) {
// do cool stuff here
console.log(data);
}
Be sure to handle the headers on your servers response so that the response gets back to your client. Here's a sample processing function I used to return data. Sorry if php isn't your server side scripting language but hopefully you'll get the idea.
`function SendResults($data) {
// Allow from any origin
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, PUT, DELETE, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
}
header("content-type: application/json");
$callback = filter_input(INPUT_GET, 'callback', FILTER_SANITIZE_SPECIAL_CHARS);
echo "$callback(" . json_encode($data) . ")";
}`
Good luck.. Hope this helps you.

Apache and Nodejs cross domain ajax issue

I am working on application in which I have used two servers hosted on same machine, one is apache which will work as basic host for serving php pages and other side nodejs for communication of rest api, whole application build upon backbone/marionette/requirejs/bootstrap.
Coming to the point, my normal pages are load from apache server like,
http://192.168.20.62/project/design.php
and I have configured my model like this,
define(['backbone'],function(Backbone){
'use strict';
return Backbone.Model.extend({
url:"http://192.168.20.62:9847/page",
defaults: {
...
}
});
});
when I try to save model I am suffering from problem of ajax cross domain call and I am ended up with error in my save communication, following is the node/express server,
var express = require('/root/node_modules/express');
var app = express();
app.configure(function () {
app.use(express.json());
app.use(express.urlencoded());
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://192.168.20.62:9847');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
})
app.post('/page', function(request, response){
console.log(request.body);
response.send(request.body);
});
app.listen(9847);
as you can see I have already written some patch in server code, but still the same, also I have added .htaccess at root level of both at
http://192.168.20.62
and
http://192.168.20.62:9847
with the following code,
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
but things are not helping in anyways, if I run chrome by disabling web security then thing are working properly.
chrome.exe --disable-web-security
Can you guys please help me to solve this puzzle, thanks in advance.
following is the error message from chrome javascript console
OPTIONS http://192.168.20.62:9847/page Origin http://192.168.20.62 is not allowed by Access-Control-Allow-Origin. jquery-2.0.3.min.js:6
XMLHttpRequest cannot load http://192.168.20.62:9847/page. Origin http://192.168.20.62 is not allowed by Access-Control-Allow-Origin.
Oops I figure out the problem, I have setup wrong url for white listing.
res.setHeader('Access-Control-Allow-Origin', 'http://192.168.20.62');
I have to whitelist the source URL which was generating cross domain, this was the only change have to do to make thing running.
Also this has browser version impact, when I have posted this issue, I was checking with firefox version 24.0.* and when I upgrade 25.0 it has stopped generating cross domain error surprisingly. But still Chrome giving natural cross domain error, when I read error message of chrome carefully I come to know that I have whitelisted wrong url.
XMLHttpRequest cannot load http://192.168.20.62:9847/page. The 'Access-Control-Allow-Origin' whitelists only 'http://192.168.20.62:9847'. Origin 'http://192.168.20.62' is not in the list, and is therefore not allowed access.
If you don't have to deal with WebSockets, then place Node.js behind Apache via mod_proxy:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule rewrite_module modules/mod_rewrite.so
# disable use as forward proxy
ProxyRequests Off
# don't handle Via: headers - we don't care about them
ProxyVia Off
# no need to transport host name - not doing virtual hosting
ProxyPreserveHost Off
ProxyPass /page/ http://192.168.20.62:9847/page/
ProxyPassReverse /page/ http://192.168.20.62:9847/page/
# If you get HTTP status code 502 (Bad Gateway), maybe this could help
SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1
In your web-page you can access your API with the same port as your Apache and you don't have any problems with Cross-Domain / Same-Origin-Policy.
You just have to separate your URIs now, e.g /page/ exists only in node.js app.
If you're serving REST only (no HTML/CSS/Images) via node.js, using JSONP would be another option. Here is a good+short description how to handle JSONP in Express

Refused to set unsafe header "Origin" when using xmlHttpRequest of Google Chrome

Got this error message:
Refused to set unsafe header "Origin"
Using this code:
function getResponse() {
document.getElementById("_receivedMsgLabel").innerHTML += "getResponse() called.<br/>";
if (receiveReq.readyState == 4 || receiveReq.readyState == 0) {
receiveReq.open("GET", "http://L45723:1802", true, "server", "server123"); //must use L45723:1802 at work.
receiveReq.onreadystatechange = handleReceiveMessage;
receiveReq.setRequestHeader("Origin", "http://localhost/");
receiveReq.setRequestHeader("Access-Control-Request-Origin", "http://localhost");
receiveReq.timeout = 0;
var currentDate = new Date();
var sendMessage = JSON.stringify({
SendTimestamp: currentDate,
Message: "Message 1",
Browser: navigator.appName
});
receiveReq.send(sendMessage);
}
}
What am I doing wrong? What am I missing in the header to make this CORS request work?
I tried removing the receiveReq.setRequestHeader("Origin", ...) call but then Google Chrome throws an access error on my receiveReq.open() call...
Why?
This is just a guess, as I use jquery for ajax requests, including CORS.
I think the browser is supposed to set the header, not you. If you were able to set the header, that would defeat the purpose of the security feature.
Try the request without setting those headers and see if the browser sets them for you.
In CORS the calling code doesn't have to do any special configuration. Everything should be handled by the browser. It's the server's job to decide if request should be allowed or not. So any time you are making a request which breaks SOP policy, the browser will try to make a CORS request for you (it will add Origin header automatically, and possibly make a preflight request if you are using some unsafe headers/methods/content types). If the server supports CORS it will respond properly and allow/disallow the request by providing CORS specific response headers like
Access-Control-Allow-Origin: *
Keep in mind that Chrome is very restrictive about 'localhost' host name. (At least it was when I was working with it). Instead use your computer name or assign it another alias in 'hosts' file. So for example don't access your site like:
http://localhost:port/myappname
Instead use:
http://mymachinename:port/myappname
or
http://mymachinealias:port/myappname
For more details please check specification.
Are you working cross-domain?
Try Brian S solution or try this:
instead of setting to localhost just pass anything... and see what happens.
receiveReq.setRequestHeader("Origin", "*");

Resources