I am using CORS plugin for chrome and it works fine when uses local machine, but in production server the error occurs:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin is therefore not allowed access.
I understand the problem, that domain server different from domain to send request, also I understand that all users will not add CORS plugin to avoid chrome specific features.
So how do I can off checking for Access-Control-Allow-Origin for concrete post request? Use Angular to send request.
return $http({
method: 'POST',
url: url,
headers:{
'Content-Type': "application/x-www-form-urlencoded"
},
data: $.param(data)
});
I need to avoid this error on prod server.
I just ran into this issue a few days ago and searched everywhere for a response. From what I gathered, the only way to do a cross-domain AJAX request is if you have control of both of the servers hosting each domain. This way you can add the necessary headers in the HTTP requests to allow for cross-domain requests. If you don't have control of both servers, you can POST to a PHP script on your server that can then POST externally and return the info you need. That's how I resolved my issue anyway. hope it helps!
Related
I have a problem with a CORS request
Access to fetch at 'https://webhook.site/f9087e12-b444-4e6b-9e64-06ba47b8c24e' from origin 'https://localhost:5001' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
My request:
fetch("https://webhook.site/f9087e12-b444-4e6b-9e64-06ba47b8c24e", {
method: 'get',
headers: new Headers({
'Access-Control-Allow-Origin': 'https://localhost:5001',
'Content-Type': 'application/json;charset=utf-8'
}),
})
.then(res => res.json())
.then(
(result) => {
console.log('res ' + result);
},
(error) => {
console.log('error ' + error);
}
)
I can’t figure out how to solve the problem.
CORS is a server side thing. Your browser is contacting webhook.site and saying "I want to download that thing f9087e12-b444-4e6b-9e64-06ba47b8c24e, what domains will you serve it to?" and webhook.site is saying e.g. "I'll only serve it to scripts that were downloaded from whatever.com" and your browser is thinking "hmm, well the script making the request was downloaded from localhost so.. denied"
You need to change the webhook.site server so it has an allow for localhost, not the client. It is the server response to the OPTIONS request that must contain the Access-Control-Allowed-Origin header, not the request from the client. Or you need to make the request without CORS in which case the browser will not make the options request.
CORS headers shall be returned from the server.
The server behind https://webhook.site/f9087e12-b444-4e6b-9e64-06ba47b8c24e shall return the header 'Access-Control-Allow-Origin': 'https://localhost:5001' in response to all requests, especially the OPTIONS request (preflight).
Best intro to the subject I have seen is https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
In a nutshell, the server shall decide if it allows CORS in general and to what resources.
The browser is responsible to protect the user by obeying to the rules defined by the server.
Hope it is helpful...
This is a browser's way of protecting it's users. Your request may be innocent, but imagine a scenario where the user goes to an innocent looking website which then uses http to send any password a user inputs to a thief. So the browser will only allow requests to the same domain or "origin".
There are ways around it, but the commonly accepted practice is to send the request to your server (localhost:5001) and your server sends a request to the other site and sends the response back to the browser.
That way all requests go through the domain that the user decided to trust by visiting.
I'm using Django with Rest framework and React to make a call to this API url.
I already enabled CORS, however, the axios request is still blocked by CORB.
Also tried to temporarily disable it, by starting Chrome with the following command line flag:
--disable features=CrossSiteDocumentBlockingAlways,CrossSiteDocumentBlockingIfIsolating
Here is the code:
componentDidMount() {
const articleID = this.props.match.params.articleID;
axios.get(`http://127.0.0.1:8000/api/${articleID}`, {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET',
'Content-Type': 'application/json',
'X-Content-Type-Options': 'nosniff'
}
}).then(res => {
this.setState({
article: res.data
});
console.log(`http://127.0.0.1:8000/api/${articleID}`);
//console.log(res.data);
});
}
This is the error
WARNING: Cross-Origin Read Blocking (CORB) blocked cross-origin response http://127.0.0.1:8000/api/1 with MIME type application/json.
How to defeat CORB and allow javascript to access local web server running on localhost (127.0.0.1) over XHR:
Select a random domain and point it to 127.0.0.1 in your HOSTS file
Direct your XHR connections to that domain instead of 127.0.0.1
You will need to enable SSL/TLS on your local web server.
a) If you are coding your own sockets server in C here is a guide on how to SSL enable them.
b) Or you can base your simple local server on a light web server that supports SSL/TLS out of the box: abyssws I chose this faster solution and had it serve files dynamically dumped out by my existing logic to specific doc paths under the server's root.
You will need to make sure that your local server's responses always include this CORS header: Access-Control-Allow-Origin: *
It should be working now.
SOLVED: added Allow-Control-Allow-Origin extension to my chrome browser and specified URL pattern. For example, localhost:8000/* and http://127.0.0.1:8000/* should be able to connect. If CORB error comes up, there's no way but to disable the chrome browser security for me :(
I have tried all things, use CORS plugin. disable web-security in chrome.
The response is coming in POSTMAN but not able to fetch it in $http.
$http({
url: "https://interview-api-staging.bytemark.co/books",
method: 'GET',
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET,OPTIONS,PUT,DELETE',
'Access-Control-Allow-Headers': 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since'
}
}).then(function(d) {
console.log(d);
});
Client has nothing to do with it. With a CORS header, you're telling the client which other servers do I trust. Those then can share your resources and client won't mind.
For example if you have two domains you tell the client so let your resources be used by your second website, you don't say I trust you as a client.
So you're protecting the server, not client. You don't want AJAX API Endpoints to be accessible by scripts hosted anywhere in the world.
A client has nothing to gain/lose from this. It's only a protection for servers because using AJAX all the URLs are clearly visible to anyone and had it been not for this protection, anybody could go-ahead run their front end using your API, only servers have to lose from this so they get to decide who can use their resources.
source.
As mentioned you don't need to do any cors related stuff in the front-end. Make sure the cors headers are sent from the backend in its response headers.
It is the server that has to protect itself so they have to tell some rules to the client which client will follow. By default, the client will accept everything.
Use CORS in your backend. Otherwise, you can check out Allow-Control-Allow-Origin: * in the Chrome Web Store, use chrome extension.
when you trying to hit through the angular app you need to turn on that extension.
otherwise you need to active CORS in your backend application
I am working on SPA MEAN app, I was developing it against Apiary mock APIs, which has the following CORS headers set:
Access-Control-Allow-Methods → OPTIONS,GET,HEAD,POST,PUT,DELETE,TRACE,CONNECT
Access-Control-Allow-Origin → *
Access-Control-Max-Age → 10
It all works fine and angular can access it using $http angular service just fine. However after adding Stormpath Angular SDK all these requests fail with following error:
XMLHttpRequest cannot load https://xxx.apiary-mock.com/workshops?type=favourite. Credentials flag is 'true', but the 'Access-Control-Allow-Credentials' header is ''. It must be 'true' to allow credentials. Origin 'http://localhost:8000' is therefore not allowed access.
I am trying to get to figure out why these requests are rejected and at what point these headers are added?
Thank you for finding this issue. The Stormpath Angular SDK does have an interceptor which sets the withCredentials: true flag for all requests. Please see the code here.
The intention is to ensure that our authentication cookies are always sent, even in a cross-domain situation. But I can see how this will be problematic if your Angular application is talking to other APIs that don't require cookies to be sent.
As a workaround, you can override our interceptor by simply adding another one:
angular.module('myapp', [
'stormpath',
'stormpath.templates'
]).config(function ($httpProvider) {
$httpProvider.interceptors.push(function() {
return {
request: function(config) {
config.withCredentials=false;
return config;
}
};
});
});
I've created an issue to discuss a better solution: https://github.com/stormpath/stormpath-sdk-angularjs/issues/72
Any time you have a SPA client served from one domain (e.g. localhost:8080) and you want that client to access an API on another domain (xxx.apiary-mock.com), the browser requires that the server domain add CORS headers correctly.
If the client and server domains are different, the browser's security model requires the server to indicate which client domains may access the server by setting the Access-Control-Allow-Origin response header (in addition to other relevant Access-Control-* headers).
I have how to work around it add these headers to apiary:
+ Response 200 (application/json)
+ Headers
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: OPTIONS,GET,HEAD,POST,PUT,DELETE,TRACE,CONNECT
Access-Control-Allow-Origin: http://localhost:8000
I am still trying to figure out where does Stormpath make those headers required though.
I'm currently deploying a basic API to my live server and I'm running into (what I think is) a CORS problem but there is some behavior going on that I can't explain.
I'm communicating from an AngularJS front-end to a Laravel 5 (+ laravel-cors) back-end.
I started testing with a simple jQuery AJAX call (below) and when I make a request from my local Vagrant environment (http://dev.example.local/test.html) to http://api.example.com/v1/matches I get an error about Access-Control-Allow-Origin. The weird thing is that the request does come through because the information is stored in the database via the Laravel-based API correctly.
$.ajax({
method: 'POST',
url: 'http://api.example.com/v1/players',
data: {
"username": "username",
"first_name": "First",
"last_name": "Last",
"nickname": ""
}
}).always(function(r) {
console.log(r);
});
Error:
XMLHttpRequest cannot load http://api.example.com/v1/players. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://other.example.com' is therefore not allowed access.
The console.log(r) returns {readyState: 0, responseJSON: undefined, status: 0, statusText: "error"}
I developed the application locally using a Homestead VM (API) and a Vagrant environment (application) and it's working correctly within these environments...
Some observations:
Each of these requests shows up with Method: POST, Status: 200 OK, Type: xhr in my Chrome Developer Tools.
Tools like Postman and PhpStorm's RESTful service tester correctly execute the request and the data is added without errors.
Any ideas on how to further debug this problem are welcome... I've been trying to wrap my head around this for the entire day now and I just don't know what's causing it.
Your server must return an appropriate Access-Control-Allow-Origin header in the response. For example, if the request is being sent from http://stackoverflow.com, then your server must return this header: Access-Control-Allow-Origin: http://stackoverflow.com. You can determine, server-side, what the origin is by looking at the Origin header on the request. If your server does not return this header in the response, you will not have any access to the properties of the response browser-side (such as the status code, headers, or message body). The Same Origin Policy is at the center of this restriction.
The reason you are not seeing any similar issues when the request is sent by Postman or PhpStorm's RESTful service tester is due to the fact that these services do not send an Origin header with the request, as they are not subject to the Same Origin policy. By default, the browser will append this header to any cross-origin ajax requests, as browsers are subject to the Same Origin Policy. In my previous scenario, the request header would look like this: Origin: http://stackoverflow.com. Browsers that implement the CORS spec are required to add this request header so the server is able to determine if the origin of the request has been whitelisted for cross-origin ajax requests. If this is the case, the server will return the proper Access-Control-Allow-Origin header. If not, it can simply omit the header. Browsers that do not implement the CORS spec will simply refuse to send such an ajax request.
Regarding your bewilderment as to why the request is being sent in the first place, that comes down to a distinction between "simple" and "non-simple" CORS requests. For simple CORS requests, the request will always be sent to the server, but the client/JS will not be able to parse the response without proper acknowledgement from the server. Some CORS requests are not simple, so to speak. These are, for example, DELETE or PATCH requests, or POST/GET requests that contain non-standard headers (such as X-headers or a Content-Type of "application/json" as opposed to "multipart/form-data"). In other words, a request is not simple if it cannot be sent without JavaScript. For example, a <form> submit, or a GET request from a <script src="..."> will always send "simple" requests. For non-simple requests, the browser must "preflight" the request. This means that the browser sends an intermediate request, called a preflight, before the original request. This preflight request is an OPTIONS request. The server must than return headers in the response to this preflight that acknowledge any non-standard properties of the original request. If it does, then the browser will send the original request.
You can read more about preflighting and CORS in general on MDN.