How does the 'Access-Control-Allow-Origin' header work?
Asked Answered
C

20

1584

Apparently, I have completely misunderstood its semantics. I thought of something like this:

  1. A client downloads JavaScript code MyCode.js from http://siteA - the origin.
  2. The response header of MyCode.js contains Access-Control-Allow-Origin: http://siteB, which I thought meant that MyCode.js was allowed to make cross-origin references to the site B.
  3. The client triggers some functionality of MyCode.js, which in turn make requests to http://siteB, which should be fine, despite being cross-origin requests.

Well, I am wrong. It does not work like this at all. So, I have read Cross-origin resource sharing and attempted to read Cross-Origin Resource Sharing in w3c recommendation.

One thing is sure - I still do not understand how I am supposed to use this header.

I have full control of both site A and site B. How do I enable the JavaScript code downloaded from the site A to access resources on the site B using this header?

P.S.: I do not want to utilize JSONP.

Copulate answered 17/5, 2012 at 13:23 Comment(4)
I'm not sure, but I believe that setting the header this way allows code on site B to fetch http://siteA/MyCode.js.Deaminate
But how??? In order to get the header value one has to fetch the resource first, but the resource is cross-origin and so shouldn't the browser block the request in the first place?Copulate
What you described actually resembles another practice, Content Security PolicyFriction
@Copulate You don't have to fetch the resource in order to get the headers. The HTTP HEADER method will return headers-only. And in the case of CORS, a preflight check is done using the HTTP OPTIONS method which doesn't return the body either. apsillers answer describes this nicely stackoverflow.com/posts/10636765/revisions.Radiosonde
B
1888

Access-Control-Allow-Origin is a CORS (cross-origin resource sharing) header.

When Site A tries to fetch content from Site B, Site B can send an Access-Control-Allow-Origin response header to tell the browser that the content of this page is accessible to certain origins. (An origin is a domain, plus a scheme and port number.) By default, Site B's pages are not accessible to any other origin; using the Access-Control-Allow-Origin header opens a door for cross-origin access by specific requesting origins.

For each resource/page that Site B wants to make accessible to Site A, Site B should serve its pages with the response header:

Access-Control-Allow-Origin: http://siteA.com

Modern browsers will not block cross-domain requests outright. If Site A requests a page from Site B, the browser will actually fetch the requested page on the network level and check if the response headers list Site A as a permitted requester domain. If Site B has not indicated that Site A is allowed to access this page, the browser will trigger the XMLHttpRequest's error event and deny the response data to the requesting JavaScript code.

Non-simple requests

What happens on the network level can be slightly more complex than explained above. If the request is a "non-simple" request, the browser first sends a data-less "preflight" OPTIONS request, to verify that the server will accept the request. A request is non-simple when either (or both) using:

  1. An HTTP verb other than GET or POST (e.g. PUT, DELETE);
  2. Non-simple request headers; the only simple requests headers are:
    • Accept;
    • Accept-Language;
    • Content-Language;
    • Content-Type (this is only simple when its value is application/x-www-form-urlencoded, multipart/form-data, or text/plain).

If the server responds to the OPTIONS preflight with appropriate response headers (Access-Control-Allow-Headers for non-simple headers, Access-Control-Allow-Methods for non-simple verbs) that match the non-simple verb and/or non-simple headers, then the browser sends the actual request.

Supposing that Site A wants to send a PUT request for /somePage, with a non-simple Content-Type value of application/json, the browser would first send a preflight request:

OPTIONS /somePage HTTP/1.1
Origin: http://siteA.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type

Note that Access-Control-Request-Method and Access-Control-Request-Headers are added by the browser automatically; you do not need to add them. This OPTIONS preflight gets the successful response headers:

Access-Control-Allow-Origin: http://siteA.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type

When sending the actual request (after preflight is done), the behavior is identical to how a simple request is handled. In other words, a non-simple request whose preflight is successful is treated the same as a simple request (i.e., the server must still send Access-Control-Allow-Origin again for the actual response).

The browsers sends the actual request:

PUT /somePage HTTP/1.1
Origin: http://siteA.com
Content-Type: application/json

{ "myRequestContent": "JSON is so great" }

And the server sends back an Access-Control-Allow-Origin, just as it would for a simple request:

Access-Control-Allow-Origin: http://siteA.com

See Understanding XMLHttpRequest over CORS for a little more information about non-simple requests.

Bueno answered 17/5, 2012 at 13:33 Comment(24)
But MyCode.js cannot reach for site B in the first place! How will this header arrive at the client? BTW, kudos for the light life glider in the avatar.Copulate
I edited with clarification: the browser actually does perform a network fetch on site B to check the Access-Control-Allow-Origin header, but it might not provide the response to the JS code on site A if the header doesn't allow site A to have it. (P.S. Thanks :) )Bueno
Indeed, I do not see any record of the download in Fiddler, unless the cross-origin request is approved. Interesting...Copulate
So why can my browser make an HTTP get request when I type it in the URL and retrieve JSON data but my javascript client cannot?Showily
@Showily A fundamental "why?" question like that is probably out of scope for this particular answer, which is just about rules & mechanics. Basically, the browser allows you, the human sitting at the computer, see any resource from any origin. It disallows scripts (which could be written by anyone) from reading resources from origins that are different from the origin of the page running the script. Some related questions are programmers.stackexchange.com/q/216605 and What is the threat model for the same origin policy?Bueno
In case of using an authentication, Access-Control-Allow-Origin does not accept the * in some browsers (FF and Chrome AFAIK). So in this case you have to specify the value from the Origin header. Hope that this will help someone.Candlelight
@Candlelight That is indeed spec-compliant behavior ("The string "*" cannot be used for a resource that supports credentials."). See also Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is trueBueno
maxcdn.com/one/visual-glossary/cors adds that "​The second domain determines whether or not to serve the content by validating the first domain, which is included as part of the request. The second domain then returns either the content or an error message back to the browser, bypassing the first domain entirely."Recommend
This worked for me in c# System.Net.Http.HttpResponseMessage response = new HttpResponseMessage(); response.Headers.Add("Access-Control-Allow-Origin", "domain/page.html");Nonoccurrence
So this mean, if site A is not allowed by site B, and site B API does DB operations and input validation, so this will all be done and then request will be rejected at browser end, even though everything is done.Gazette
How preFlight request escapes all input validations and db calls?Gazette
@Gazette "this will all be done and then request will be rejected at browser end" -- if I understand you, this is exactly what a preflight prevents. First, the browser sends a preflight OPTIONS, and it waits ito send the real request that will trigger some action on the server. If the server does not say, "Yes, send the real request," by sending appropriate an CORS response, then the browser will not send the real request.Bueno
I have few doubts regarding CORS: 1. So, if the sever API that we are trying to access the response does not enable CORS Filter access, do Chrome Plugins can work for by-passing? 2. What should I in my production environment for enabling this CORS filter? For Ex. If I am trying to access an API like, the Facebook API to login/ Google API to sign In to my webpage, how can these filter work, as they might have restricted the cross-domain access. So, in that case how can these filter by-pass done?Manicotti
@Ashfaque (1) Chrome Extensions may request permission to access specific origins in ways that normal web pages cannot. (2) Login APIs like OAuth don't use XHR/Ajax. They actually redirect the top-level page to some other page like https://google.com/auth?token=...&redirect=... in a way that doesn't cause a cross-origin request.Bueno
For completeness, to anyone that is using access-control-allow-origin dynamically (changing the URL value based on the requesting origin) instead of *, you must also include the header Vary: Origin. See fetch.spec.whatwg.org/#cors-protocol-and-http-cachesGig
Thanks to your explanation I could solve the CORS issue I had with pre-flight requests. I modified the Content-Type of the POST request to my server from "application/json" to "text/plain" to avoid the pre-flight requests from happening.Response
This post has been very useful to me, here is another page with information about CORS and the Access-Control-Allow-Origin header: portswigger.net/web-security/cors/access-control-allow-originClearstory
While allowing Access-Control-Allow-Origin will effect the website security, some of the servers didn't allowed to do that, so what's the alternative?Overblouse
@Overblouse If you're trying to do a croos-origin Ajax fetch, you probably want a reverse proxy. There are also many other approaches on hat Q&A, depending on what same-origin restriction you need to work around.Bueno
@Bueno Thanks for quick resposnse, I m not much aware of ajax etc i have my site on wordpress for which google is not caching it properly it refuse to load url of js and css due to which cache version is distorted awaismalik.tinytake.com/tt/NTI0NDA1M18xNjQwMTA1MAOverblouse
When you say Site A requests from Site B, does that mean that the client/browser requests a page from Site A and the browser requests from Site B?Langham
@dougd_in_nc It means that the browser is displaying a page from Site A (e.g., a URL from Site A is in the address bar) and then a script running on that page tries to fetch and read a resource hosted by Site B (e.g., the site A page executes fetch("https://siteB/something.txt")).Bueno
I'm still trying to get my head around this. I have code on my site which tries to search images using freepik's api. I've been trying to set the headers on my server so my browser will allow responses from api.freepik.com, but it sounds like api.freepik.com needs to add my site to their allow list. Is that correct?Scolecite
@Scolecite That's correct. If Freepik doesn't serve CORS and you want to get around this, you have to run your own server which will fetch the Freepik API and serve the results to your web page with CORS or simply under the same origin.Bueno
E
151

Cross-Origin Resource Sharing - CORS (A.K.A. Cross-Domain AJAX request) is an issue that most web developers might encounter, according to Same-Origin-Policy, browsers restrict client JavaScript in a security sandbox, usually JS cannot directly communicate with a remote server from a different domain. In the past developers created many tricky ways to achieve Cross-Domain resource request, most commonly using ways are:

  1. Use Flash/Silverlight or server side as a "proxy" to communicate with remote.
  2. JSON With Padding (JSONP).
  3. Embeds remote server in an iframe and communicate through fragment or window.name, refer here.

Those tricky ways have more or less some issues, for example JSONP might result in security hole if developers simply "eval" it, and #3 above, although it works, both domains should build strict contract between each other, it neither flexible nor elegant IMHO:)

W3C had introduced Cross-Origin Resource Sharing (CORS) as a standard solution to provide a safe, flexible and a recommended standard way to solve this issue.

The Mechanism

From a high level we can simply deem CORS as a contract between client AJAX call from domain A and a page hosted on domain B, a typical Cross-Origin request/response would be:

DomainA AJAX request headers

Host DomainB.com
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/json
Accept-Language en-us;
Accept-Encoding gzip, deflate
Keep-Alive 115
Origin http://DomainA.com 

DomainB response headers

Cache-Control private
Content-Type application/json; charset=utf-8
Access-Control-Allow-Origin DomainA.com
Content-Length 87
Proxy-Connection Keep-Alive
Connection Keep-Alive

The blue parts I marked above were the kernal facts, "Origin" request header "indicates where the cross-origin request or preflight request originates from", the "Access-Control-Allow-Origin" response header indicates this page allows remote request from DomainA (if the value is * indicate allows remote requests from any domain).

As I mentioned above, W3 recommended browser to implement a "preflight request" before submiting the actually Cross-Origin HTTP request, in a nutshell it is an HTTP OPTIONS request:

OPTIONS DomainB.com/foo.aspx HTTP/1.1

If foo.aspx supports OPTIONS HTTP verb, it might return response like below:

HTTP/1.1 200 OK
Date: Wed, 01 Mar 2011 15:38:19 GMT
Access-Control-Allow-Origin: http://DomainA.com
Access-Control-Allow-Methods: POST, GET, OPTIONS, HEAD
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Max-Age: 1728000
Connection: Keep-Alive
Content-Type: application/json

Only if the response contains "Access-Control-Allow-Origin" AND its value is "*" or contain the domain who submitted the CORS request, by satisfying this mandtory condition browser will submit the actual Cross-Domain request, and cache the result in "Preflight-Result-Cache".

I blogged about CORS three years ago: AJAX Cross-Origin HTTP request

Eastbourne answered 23/1, 2014 at 13:54 Comment(4)
This answer made me realize why i was suddenly getting an issue without using this header for POST and GET requests. I had accidently opened the index.html file directly from disk, so the URL the client was accessing on node.js was thought to be cross-domain, while it was simply running on localhost. Accessing via the URL (as one would usually do) "solved" my issue...Realm
I have a public fetch API. But some people were telling to enable CORS as it blocks their requests. I know there is an npm package called cors. But I saw that many Public APIs do not have CORS enabled. I also read some articles about the security risks in CORS. I was asking that will it be wrong to enable CORS. Few people are calling the API from the client-side code that is running in the browsers. Any suggestion is gratefully accepted.Fishman
What I read on your last link: wayneye.com currently does not have any sponsors for you.Whippoorwill
@Whippoorwill I updated link to: wayneye.me/Ajax-Cross-Origin-HTTP-request Thanks :)Eastbourne
G
96

According to this Mozilla Developer Network article,

A resource makes a cross-origin HTTP request when it requests a resource from a different domain, or port than the one which the first resource itself serves.

Enter image description here

An HTML page served from http://domain-a.com makes an <img> src request for http://domain-b.com/image.jpg. Many pages on the web today load resources like CSS style sheets, images and scripts from separate domains (thus it should be cool).

Same-Origin Policy

For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and Fetch follow the same-origin policy. So, a web application using XMLHttpRequest or Fetch could only make HTTP requests to its own domain.

Cross-Origin Resource Sharing (CORS)

To improve web applications, developers asked browser vendors to allow cross-domain requests.

The Cross-origin resource sharing (CORS) mechanism gives web servers cross-domain access controls, which enable secure cross-domain data transfers. Modern browsers use CORS in an API container - such as XMLHttpRequest or fetch - to mitigate risks of cross-origin HTTP requests.

How CORS works (Access-Control-Allow-Origin header)

Wikipedia:

The CORS standard describes new HTTP headers which provide browsers and servers a way to request remote URLs only when they have permission.

Although some validation and authorization can be performed by the server, it is generally the browser's responsibility to support these headers and honor the restrictions they impose.

Example

  1. The browser sends the OPTIONS request with an Origin HTTP header.

The value of this header is the domain that served the parent page. When a page from http://www.example.com attempts to access a user's data in service.example.com, the following request header would be sent to service.example.com:

lang-none Origin: http://www.example.com

  1. The server at service.example.com may respond with:
  • An Access-Control-Allow-Origin (ACAO) header in its response indicating which origin sites are allowed. For example:

    Access-Control-Allow-Origin: http://www.example.com

  • An error page if the server does not allow the cross-origin request

  • An Access-Control-Allow-Origin (ACAO) header with a wildcard that allows all domains:

    Access-Control-Allow-Origin: *

Glycogen answered 5/3, 2017 at 6:39 Comment(0)
S
49

Whenever I start thinking about CORS, my intuition about which site hosts the headers is incorrect, just as you described in your question. For me, it helps to think about the purpose of the same-origin policy.

The purpose of the same-origin policy is to protect you from malicious JavaScript on siteA.com accessing private information you've chosen to share only with siteB.com. Without the same-origin policy, JavaScript written by the authors of siteA.com could have your browser make requests to siteB.com, using your authentication cookies for siteB.com. In this way, siteA.com could steal the secret information you share with siteB.com.

Sometimes you need to work cross domain, which is where CORS comes in. CORS relaxes the same-origin policy for siteB.com, using the Access-Control-Allow-Origin header to list other domains (siteA.com) that are trusted to run JavaScript that can interact with siteB.com.

To understand which domain should serve the CORS headers, consider this. You visit malicious.com, which contains some JavaScript that tries to make a cross domain request to mybank.com. It should be up to mybank.com, not malicious.com, to decide whether or not it sets CORS headers that relax the same-origin policy, allowing the JavaScript from malicious.com to interact with it. If malicous.com could set its own CORS headers allowing its own JavaScript access to mybank.com, this would completely nullify the same-origin policy.

I think the reason for my bad intuition is the point of view I have when developing a site. It's my site, with all my JavaScript. Therefore, it isn't doing anything malicious, and it should be up to me to specify which other sites my JavaScript can interact with. When in fact I should be thinking: Which other sites' JavaScript are trying to interact with my site and should I use CORS to allow them?

Slander answered 28/1, 2018 at 18:47 Comment(2)
Given paragraph 2, do you have siteA, siteB backwards in paragraph 3? I could be misunderstanding, but the earlier paragraph seems to imply its siteA that is running the JS in question?Rojas
From OP - "I think the reason for my bad intuition is the point of view I have when developing a site. It's my site, with all my JavaScript, therefore it isn't doing anything malicious and it should be up to me to specify which other sites my JavaScript can interact with. " - for those who first thought like this (as I did), there is another rule, one that is not CORS, for this: CSP (consent security policy) - using CSP you can specify which site/url your site is able to visit/reach.Expiate
C
22

From my own experience, it's hard to find a simple explanation why CORS is even a concern.

Once you understand why it's there, the headers and discussion becomes a lot clearer. I'll give it a shot in a few lines.


It's all about cookies. Cookies are stored on a client by their domain.

An example story: On your computer, there's a cookie for yourbank.com. Maybe your session is in there.

Key point: When a client makes a request to the server, it will send the cookies stored under the domain for that request.

You're logged in on your browser to yourbank.com. You request to see all your accounts, and cookies are sent for yourbank.com. yourbank.com receives the pile of cookies and sends back its response (your accounts).

If another client makes a cross origin request to a server, those cookies are sent along, just as before. Ruh roh.

You browse to malicious.com. Malicious makes a bunch of requests to different banks, including yourbank.com.

Since the cookies are validated as expected, the server will authorize the response.

Those cookies get gathered up and sent along - and now, malicious.com has a response from yourbank.

Yikes.


So now, a few questions and answers become apparent:

  • "Why don't we just block the browser from doing that?" Yep. That's CORS.

  • "How do we get around it?" Have the server tell the request that CORS is OK.

Connected answered 18/11, 2019 at 19:40 Comment(4)
I like this answer and I feel like this is right, but I don't understand why it seems like it's only the front-end that throws an error, and the backend might still process the request. I wrote a question about it stackoverflow.com/questions/69559952/…Encrata
The backend only sees one request, from one URL. The backend for yourbank.com doesn't (definitively) know that it's malicious.com making the request. The browser is the only place that keeps track of all of the different domains you've visitedConnected
Wouldn't it make much more sense that the request is indeed allowed to pass, but the cookies that are sent are always from the requesting domain?Sherikasherill
@Sherikasherill you understand it perfectly, they are. The problem is that malicious.com can send a request to yourbank.com...then the cookies are gathered up for yourbank.com and sent. The response then comes back to malicious.com.Connected
C
16

1. A client downloads javascript code MyCode.js from http://siteA - the origin.

The code that does the downloading - your html script tag or xhr from javascript or whatever - came from, let's say, http://siteZ. And, when the browser requests MyCode.js, it sends an Origin: header saying "Origin: http://siteZ", because it can see that you're requesting to siteA and siteZ != siteA. (You cannot stop or interfere with this.)

2. The response header of MyCode.js contains Access-Control-Allow-Origin: http://siteB, which I thought meant that MyCode.js was allowed to make cross-origin references to the site B.

no. It means, Only siteB is allowed to do this request. So your request for MyCode.js from siteZ gets an error instead, and the browser typically gives you nothing. But if you make your server return A-C-A-O: siteZ instead, you'll get MyCode.js . Or if it sends '*', that'll work, that'll let everybody in. Or if the server always sends the string from the Origin: header... but... for security, if you're afraid of hackers, your server should only allow origins on a shortlist, that are allowed to make those requests.

Then, MyCode.js comes from siteA. When it makes requests to siteB, they are all cross-origin, the browser sends Origin: siteA, and siteB has to take the siteA, recognize it's on the short list of allowed requesters, and send back A-C-A-O: siteA. Only then will the browser let your script get the result of those requests.

Copernicus answered 27/2, 2016 at 1:37 Comment(0)
T
16

Using React and Axios, join a proxy link to the URL and add a header as shown below:

https://cors-anywhere.herokuapp.com/ + Your API URL

Just adding the proxy link will work, but it can also throw an error for No Access again. Hence it is better to add a header as shown below.

axios.get(`https://cors-anywhere.herokuapp.com/[YOUR_API_URL]`,{headers: {'Access-Control-Allow-Origin': '*'}})
      .then(response => console.log(response:data);
  }

Warning: Not to be used in production

This is just a quick fix. If you're struggling with why you're not able to get a response, you can use this. But again it's not the best answer for production.

Thesaurus answered 16/10, 2017 at 15:53 Comment(3)
Please don't do this. Using a proxy link is like handing over user cookies to a middle-man. Should be illegal IMHOMordent
this was useful for me! Except rather than using the * (which has security issues), I limited Access Control to the exact address i'm using to learn with... in my case 'reqres.in/api/register'Lucio
In my case it was sampledataapi.com/API/index.php/getcountryAvram
R
14

I worked with Express.js 4, Node.js 7.4 and Angular, and I had the same problem. This helped me:

a) server side: in file app.js I add headers to all responses, like:

app.use(function(req, res, next) {
    res.header('Access-Control-Allow-Origin', req.headers.origin);
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

This must be before all routes.

I saw a lot of added this headers:

res.header("Access-Control-Allow-Headers","*");
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');

But I don’t need that,

b) client side: in sending by Ajax, you need to add "withCredentials: true," like:

$http({
     method: 'POST',
     url: 'url',
     withCredentials: true,
     data : {}
   }).then(function(response){
       // Code
   }, function (response) {
       // Code
});
Rempe answered 6/2, 2017 at 8:19 Comment(2)
res.header('Access-Control-Allow-Origin', req.headers.origin); is the same as res.header('Access-Control-Allow-Origin', '*');Sissy
* and req.headers.origin are not the same... * is not allowed when using credentials.Chiropodist
P
12

If you are using PHP, try adding the following code at the beginning of the php file:

If you are using localhost, try this:

header("Access-Control-Allow-Origin: *");

If you are using external domains such as server, try this:

header("Access-Control-Allow-Origin: http://www.website.com");
Purify answered 18/1, 2017 at 15:30 Comment(0)
D
12

If you want just to test a cross-domain application in which the browser blocks your request, then you can just open your browser in unsafe mode and test your application without changing your code and without making your code unsafe.

From macOS, you can do this from the terminal line:

open -a Google\ Chrome --args --disable-web-security --user-data-dir
Dubose answered 22/2, 2017 at 16:32 Comment(0)
D
7

In Python, I have been using the Flask-CORS library with great success. It makes dealing with CORS super easy and painless. I added some code from the library's documentation below.

Installing:

pip install -U flask-cors

Simple example that allows CORS for all domains on all routes:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def helloWorld():
  return "Hello, cross-origin-world!"

For more specific examples, see the documentation. I have used the simple example above to get around the CORS issue in an Ionic application I am building that has to access a separate flask server.

Desberg answered 25/1, 2018 at 11:10 Comment(0)
T
5

Simply paste the following code in your web.config file.

Noted that, you have to paste the following code under <system.webServer> tag

<httpProtocol>
  <customHeaders>
   <add name="Access-Control-Allow-Origin" value="*" />
   <add name="Access-Control-Allow-Headers" value="Content-Type" />
   <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
  </customHeaders>
</httpProtocol>
Trump answered 20/1, 2019 at 4:35 Comment(2)
This helped me. I was enabling cors in WebApiConfig.cs.but I used the above code and put it on the web. config and remove the WebApiConfig.cs code. It worked like charm. ThanksPostliminy
What system? IIS/ASP.NET? web.config fileHappening
C
5

I can't configure it on the back-end server, but with these extensions in the browsers, it works for me:

For Firefox:

CORS Everywhere

For Google Chrome:

Allow CORS: Access-Control-Allow-Origin

Note: CORS works for me with this configuration:

Allow CORS options

CORS Everywhere options

Commensal answered 10/3, 2021 at 9:49 Comment(0)
G
3

For cross origin sharing, set header: 'Access-Control-Allow-Origin':'*';

Php: header('Access-Control-Allow-Origin':'*');

Node: app.use('Access-Control-Allow-Origin':'*');

This will allow to share content for different domain.

Griskin answered 28/11, 2016 at 2:39 Comment(0)
T
2

Nginx and Apache

As an addition to apsiller's answer, I would like to add a wiki graph which shows when a request is simple or not (and OPTIONS pre-flight request is send or not)

Enter image description here

For a simple request (e.g., hotlinking images), you don't need to change your server configuration files, but you can add headers in the application (hosted on the server, e.g., in PHP) like Melvin Guerrero mentions in his answer - but remember: if you add full CORS headers in your server (configuration) and at same time you allow simple CORS in the application (e.g., PHP), this will not work at all.

And here are configurations for two popular servers:

  • turn on CORS on Nginx (nginx.conf file)

    location ~ ^/index\.php(/|$) {
       ...
        add_header 'Access-Control-Allow-Origin' "$http_origin" always; # if you change "$http_origin" to "*" you shoud get same result - allow all domain to CORS (but better change it to your particular domain)
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        if ($request_method = OPTIONS) {
            add_header 'Access-Control-Allow-Origin' "$http_origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above)
            add_header 'Access-Control-Allow-Credentials' 'true';
            add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';  # arbitrary methods
            add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin'; # arbitrary headers
            add_header 'Content-Length' 0;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            return 204;
        }
    }
  • turn on CORS on Apache (.htaccess file)

    # ------------------------------------------------------------------------------
    # | Cross-domain Ajax requests                                                 |
    # ------------------------------------------------------------------------------
    
    # Enable cross-origin Ajax requests.
    # http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
    # http://enable-cors.org/
    
    # change * (allow any domain) below to your domain
    Header set Access-Control-Allow-Origin "*"
    Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
    Header always set Access-Control-Allow-Headers "My-First-Header,My-Second-Header,Authorization, content-type, csrf-token"
    Header always set Access-Control-Allow-Credentials "true"
Thorn answered 15/5, 2020 at 9:33 Comment(0)
E
1

The Access-Control-Allow-Origin response header indicates whether the response can be shared with requesting code from the given origin.

Header type                 Response header
-------------------------------------------
Forbidden header name       no

A response that tells the browser to allow code from any origin to access a resource will include the following:

Access-Control-Allow-Origin: *

For more information, visit Access-Control-Allow-Origin...

Eskilstuna answered 31/1, 2019 at 11:49 Comment(1)
Related: Answers entirely copied though properly attributedHappening
O
0

Note: Only a temporary solution for testing

For those who can't control the backend for Options 405 Method Not Allowed, here is a workaround for theChrome browser.

Execute in the command line:

"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="path_to_profile"

Example:

"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="C:\Users\vital\AppData\Local\Google\Chrome\User Data\Profile 2"

Oddity answered 18/6, 2020 at 11:30 Comment(2)
Please also mention the SEVERE RISKS of doing this w.r.t security and possible data breach. Also, note that this is never a RECOMMENDED solution but just for testing something during development and that too very cautiously.Defibrillator
You should never do this, its a breach of security and this will never help others to understand how to work with CORS. AVOID THIS AT ALL COST PLZNkrumah
T
0

For .NET Core 3.1 API With Angular

Startup.cs : Add CORS

    //SERVICES
    public void ConfigureServices(IServiceCollection services){

        //CORS (Cross Origin Resource Sharing)
        //=====================================
        services.AddCors();
    }

    //MIDDLEWARES
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseRouting();

        //ORDER: CORS -> Authentication -> Authorization)
        //CORS (Cross Origin Resource Sharing)
        //=====================================  
        app.UseCors(x=>x.AllowAnyHeader().AllowAnyMethod().WithOrigins("http://localhost:4200"));

        app.UseHttpsRedirection();
    }
}

Controller : Enable CORS For Authorized Controller

 //Authorize all methods inside this controller
 [Authorize]
 [EnableCors()]
 public class UsersController : ControllerBase
 {
    //ActionMethods
 }
Tallou answered 25/10, 2021 at 17:1 Comment(0)
S
0

TLDR: CORS is a server setting for allowing all or certain trusted domains to interact with the server.

Here is a short explanation using two different scenarios for an imaginary website mysite.com:

Scenario A: CORS setting will only allow the origin domain to interact with the server. Scenario B: CORS setting will allow external.com to interact with the server by adding external.com to the list of allowed origins.

For scenario A, a user visit mysite.com and their browser queries the server and gets a response. All is fine since the requests are coming through the mysite.com domain.

Also for scenario A, external.com tries to make requests to your server to display on their site. Maybe they want to display your logo and add an html element with src="mysite.com/logo.svg" Your server can see that the request going to mysite.com/logo.svg comes from external.com. Because only origin mysite.com is allowed in the CORS policy, the request will be blocked and external.com will get a CORS error.

For scenario B, external.com is added as a trusted origin on the server for mysite.com. When external.com sends a request to "mysite.com/logo.svg", the server can see that the domain external.com is allowed and will return the resource. The image logo.svg is displayed on external.com without any issues.

If you allow all origins with wildcard *, any site can interact with your server in the same way as in scenario B.

Snazzy answered 13/3 at 13:1 Comment(0)
N
-3

It's odd but CORS issues might happen because you are trying to request via client side ajax from a react, angular, jquery apps that are frontend basic libs.

You must request from a backend application.

You are trying to request from a frontend API, but the API you are trying to consume is expecting this request to be made from a backend application and it will never accept client side requests.

I tried a request from frontend that did not work, then I made the same request using curl and it was successful.

Nonresistant answered 7/2, 2023 at 21:44 Comment(1)
I don't understand what you mean. How can a web server know if a request comes from frontend or from backend? It's all just another HTTP request.Male

© 2022 - 2024 — McMap. All rights reserved.