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

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", "*");

Related

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.

CORS issue with SignalR - Origin not allowed

So I've read up on all the previous questions on this, but following the steps don't seem to be working for me. I'm getting the "Origin * is not allowed by Access-Control-Allow-Origin", but that doesn't make sense to me. If I open the same request in Chrome in it's own tab, and look at the network tab, I see the following CORS headers intact. Also, the hubs generate just fine. I'm using Web API, .NET 4.5, and the rc2 of SignalR. I also tried removing the Allow-Credentials in the web.config, but that didn't help either.
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:x-requested-with,X-CustomAuth,Content-Type,X-Impersonate
Access-Control-Allow-Methods:GET,OPTIONS,PUT,DELETE,HEADER
Access-Control-Allow-Origin:*
I've also set jQuery.support.cors to true, even though it was already as true, I'm using JQuery 1.9, and here's my connection to the server and hub:
jQuery.support.cors = true;
$.connection.hub.url = 'http://myserver/api/signalr';
$.connection.hub.start({ transport: 'longPolling', xdomain: true });
I've also tried this to connect, both with same issue.
$.connection('http://myserver/api/signalr/echo').start(function () {
console.log('Connected');
$.connection.hub.start().done(function() {
$log.info('Connected to hub.');
});
});
The * value cannot be used with the Access-Control-Allow-Origin header if Access-Control-Allow-Credentials is true. Try either one of the following:
Drop the Access-Control-Allow-Credentials header entirely.
Change the value of the Access-Control-Allow-Origin from * to the actual value of the Origin header.
#1 might be easier to do, but #2 is required if you need to support cookies.
According to the official doc, you should NOT be using jQuery.support.cors
Don't set jQuery.support.cors to true in your code.
Link to the official doc: official doc

Disable cache in ExtLib REST control (which uses dojox.data.JsonRestStore)

In my XPage I have a xe:djxDataGrid (dojox.grid.datagrid) which uses xe:restService which seems to use dojox.data.JsonRestStore.
Everything works fine without proxy but my client accesses the application via a proxy because of corporate policy. After a user updates data in the DataGrid it shows old values when accessed behind the proxy.
When the REST Control/JsonRestStore sends an ajax GET request to get data, there is no Cache-Control parameter in request headers. And Domino does not place Expires parameter in the reponse headers. I believe that's why the old version of the GET request gets cached by the proxy.
We have tried to disable cache in browsers but that does not help which indicates the proxy is caching the requests.
I believe this could be solved either by:
Setting Cache-Control parameter in request headers OR
Setting Expires parameter in response headers
But I haven't found a way to set either of these. For the XPage Domino sets Expires:-1 response header but not for the ajax GET request which is:
/mypage.xsp/?$$viewid=!ddrg6o7q1z!&$$axtarget=view:_id1:_id2:callback1:restService1
This returns the JSON data to JsonRestStore and gets cached by the proxy.
One options is to try to get an exception to the proxy so requests to this site would bypass the proxy cache. But exceptions are generally not easy to get thru.
Any ideas? Thanks.
Update1
My colleque suggested that I could intercept the xhr GET requests made by dojox.data.JsonRestStore and add a time parameter to the URL to prevent cache. Here is my question about that:
Prevent cache in every Dojo xhr request on page
Update2
#SvenHasselbach has a great solution for preventing cache for all xhrs:
http://openntf.org/XSnippets.nsf/snippet.xsp?id=cache-prevention-for-dojo-xhr-requests
It seems to work perfectly, &dojo.preventCache= parameter is added to the URLs and the requests seem to return correct JSON also with this parameter. But the DataGrid stops working when I use that code. Every xhr causes this error:
Tried with Firefox and Chrome. The first page of data still loads because xhr interception is not yet in place but the subsequent pages show only "..." in each cell.
The solution is Sven Hasselbach's code in the comment section of Julian Buss's blog which needs to be slightly modified.
I changed xhrPost to xhrGet and did not place the code to dojo.addOnLoad. When placed there it was not effective in the first XHR by the DataGrid/Store.
I also removed the headers modification because it overrides existing headers. When the REST control requests data from server with xhrGet the URL is always the same and rows requested are in HTTP header like this:
Range: items=0-9
This (and other) headers disappear when the original code is used. To just add headers we would have take the existing headers from args and append to them. I didn't see a need for that because it should be enough to add the parameter in the URL. Here is the extremely simple code I'm using:
if( !(dojo._xhrGet )) {
dojo._xhrGet = dojo.xhrGet;
}
dojo.xhrGet = function (args) {
args['preventCache'] = true;
return dojo._xhrGet(args);
}
Now I'm getting all rows and all XHR Get URLs have &dojo.preventCache= parameter which is exactly what I wanted. Next we'll test in customer environment to see if this solves their problem.
Update
As Julian points out in his blog I could also use a Web Site Rule to set Expires or cache-control http response headers.
Update
The customer reports it's working now for them!

XMLHttpRequest over SSL doesn't return any data

I'm trying to use XMLHttpRequest over SSL for a login system. Currently, I'm just testing the capabilities of XMLHttpRequest over SSL to make sure it indeed works. So here's what I'm testing:
Relevant Javascript:
xml_request.open("POST", "https://......", true);
xml_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xml_request.setRequestHeader("Content-length", 0);
xml_request.setRequestHeader("Connection", "close");
xml_request.send();
alert(xml_request.reponseText); //displayed using the appropriate onreadystatechange handler
PHP Script:
print json_encode(array(
"text" => "this is text"
));
Now, using http the request works fine; xml_request.responseText holds the JSON encoded string. When I use https, xml_request.responseText is defined, but it's an empty string.
Does anyone why this is and/or how to fix this?
Thanks much,
Dale
Usually, any certificate mismatch will prevent you from connecting. Can you open the site URL with a browser and check for the certificate settings on the server to see if anything is out of the ordinary or giving you warning messages?

NETWORK_ERROR: XMLHttpRequest Exception 101

I am getting this Error
NETWORK_ERROR: XMLHttpRequest Exception 101
when trying to get XML content from one site.
Here is my code:
var xmlhttp;
if(window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
if (xmlhttp==null) {
alert ("Your browser does not support XMLHTTP!");
return;
}
xmlhttp.onReadyStateChange=function() {
if(xmlhttp.readyState==4) {
var value =xmlhttp.responseXML;
alert(value);
}
}
xmlhttp.open("GET",url,false);
xmlhttp.send();
//alert(xmlhttp.responseXML);
}
xmlhttp.open("GET",url,false);
xmlhttp.send(null);
Does any one have a solution?
If the url you provide is located externally to your server, and the server has not allowed you to send requests, you have permission problems. You cannot access data from another server with a XMLHttpRequest, without the server explicitly allowing you to do so.
Update: Realizing this is now visible as an answer on Google, I tried to find some documentation on this error. That was surprisingly hard.
This article though, has some background info and steps to resolve. Specifically, it mentions this error here:
As long as the server is configured to allow requests from your web application's origin, XMLHttpRequest will work. Otherwise, an INVALID_ACCESS_ERR exception is thrown
An interpretation of INVALID_ACCESS_ERR seems to be what we're looking at here.
To solve this, the server that receives the request, must be configured to allow the origin. This is described in more details at Mozilla.
The restriction that you cannot access data from another server with a XMLHttpRequest can apply even if the url just implies a remote server.
So:
url = "http://www.myserver.com/webpage.html"
may fail,
but:
url = "/webpage.html"
succeed - even if the request is being made from www.myserver.com
Request aborted because it was cached or previously requested? It seems the XMLHttpRequest Exception 101 error can be thrown for several reasons. I've found that it occurs when I send an XMLHttpRequest with the same URL more than one time. (Changing the URL by appending a cache defeating nonsense string to the end of the URL allows the request to be repeated. -- I wasn't intending to repeat the request, but events in the program caused it to happen and resulted in this exception).
Not returning the correct responseText or responseXML in the event of a repeated request is a bug (probably webKit).
When this exception occurred, I did get an onload event with readyState==4 and the request object state=0 and responseText=="" and responseXML==null. This was a cross domain request, which the server permits.
This was on an Android 2.3.5 system which uses webKit/533.1
Anyone have documentation on what the exception is supposed to mean?
Something like this happened with me when I returned incorrect XML (I put an attribute in the root node). In case this helps anyone.
xmlhttp.open("GET",url, true);
set the async part to true
I found a very nice article with 2 diferent solutions.
The first one implementing jQuery and JSONP, explaining how simple it is.
The second approach, it's redirecting trough a PHP call. Very simple and very nice.
http://mayten.com.ar/blog/42-ajax-cross-domain
Another modern method of solving this problem is Cross Origin Ressource Sharing.
HTML5 offers this feature. You can "wrap" your XMLhttp request in this CORS_request and
if the target browser supports this feature, you can use it and wont have no problems.
EDIT:
Additionaly i have to add that there are many reasons which can cause this Issue.
Not only a Cross Domain Restriction but also simply wrong Settings in your WEB.CONFIG of your Webservice.
Example IIS(.NET):
To enable HTTP access from external sources ( in my case a compiled Phonegap app with CORS request ) you have to add this to your WEB.CONFIG
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
Another scenario:
I got two webservices running... One on Port 80 and one on Port 90. This also gave me an XML HTTP Request Error. I even dont know why :). Nevertheless i think this can help many not well experienced readers.

Resources