Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
323 views
in Technique[技术] by (71.8m points)

javascript - Access Control Origin Header error using Axios

I'm making an API call using Axios in a React Web app. However, I'm getting this error in Chrome:

XMLHttpRequest cannot load
https://example.restdb.io/rest/mock-data. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8080' is therefore not allowed
access. 
{
    axios
      .get("https://example.restdb.io/rest/mock-data", {
        headers: {
          "x-apikey": "API_KEY",
        },
        responseType: "json",
      })
      .then((response) => {
        this.setState({ tableData: response.data });
      });
}

I have also read several answers on Stack Overflow about the same issue, titled Access-Control-Allow-Origin but still couldn't figure out how to solve this. I don't want to use an extension in Chrome or use a temporary hack to solve this. Please suggest the standard way of solving the above issue.

After trying out few answers I have tried with this,

headers: { 
  'x-apikey': '59a7ad19f5a9fa0808f11931',
  'Access-Control-Allow-Origin' : '*',
  'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,PATCH,OPTIONS',
},

Now I get the error as,

Request header field Access-Control-Allow-Origin is not
allowed by Access-Control-Allow-Headers in preflight response 
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I'll have a go at this complicated subject.

What is origin?

The origin itself is the name of a host (scheme, hostname, and port) i.g. https://www.google.com or could be a locally opened file file:// etc.. It is where something (i.g. a web page) originated from. When you open your web browser and go to https://www.google.com, the origin of the web page that is displayed to you is https://www.google.com. You can see this in Chrome Dev Tools under Security:

enter image description here

The same applies for if you open a local HTML file via your file explorer (which is not served via a server):

enter image description here

What has this got to do with CORS issues?

When you open your browser and go to https://website.com, that website will have the origin of https://website.com. This website will most likely only fetch images, icons, js files and do API calls towards https://website.com, basically it is calling the same server as it was served from. It is doing calls to the same origin.

If you open your web browser and open a local HTML file and in that html file there is javascript which wants to do a request to google for example, you get the following error:

enter image description here

The same-origin policy tells the browser to block cross-origin requests. In this instance origin null is trying to do a request to https://www.google.com (a cross-origin request). The browser will not allow this because of the CORS Policy which is set and that policy is that cross-origin requests is not allowed.

Same applies for if my page was served from a server on localhost:

enter image description here

Localhost server example

If we host our own localhost API server running on localhost:3000 with the following code:

const express = require('express')
const app = express()
 
app.use(express.static('public'))

app.get('/hello', function (req, res) {
    // res.header("Access-Control-Allow-Origin", "*");
    res.send('Hello World');
})
 
app.listen(3000, () => {
    console.log('alive');
})

And open a HTML file (that does a request to the localhost:3000 server) directory from the file explorer the following error will happen:

enter image description here

Since the web page was not served from the localhost server on localhost:3000 and via the file explorer the origin is not the same as the server API origin, hence a cross-origin request is being attempted. The browser is stopping this attempt due to CORS Policy.

But if we uncomment the commented line:

const express = require('express')
const app = express()
 
app.use(express.static('public'))

app.get('/hello', function (req, res) {
    res.header("Access-Control-Allow-Origin", "*");
    res.send('Hello World');
})
 
app.listen(3000, () => {
    console.log('alive');
})

And now try again:

enter image description here

It works, because the server which sends the HTTP response included now a header stating that it is ok for cross-origin requests to happen to the server, this means the browser will let it happen, hence no error.

How to fix things (One of the following)

  • Serve the page from the same origin as where the requests you are making reside (same host).
  • Allow the server to receive cross-origin requests by explicitly stating it in the response headers.
  • If using a reverse proxy such as NGINX, configure NGINX to send response headers that allow CORS.
  • Don't use a browser. Use cURL for example, it doesn't care about CORS Policies like browsers do and will get you what you want.

Example flow

Following is taken from: https://web.dev/cross-origin-resource-sharing/#how-does-cors-work

Remember, the same-origin policy tells the browser to block cross-origin requests. When you want to get a public resource from a different origin, the resource-providing server needs to tell the browser "This origin where the request is coming from can access my resource". The browser remembers that and allows cross-origin resource sharing.

  • Step 1: client (browser) request When the browser is making a cross-origin request, the browser adds an Origin header with the current origin (scheme, host, and port).

  • Step 2: server response On the server side, when a server sees this header, and wants to allow access, it needs to add an Access-Control-Allow-Origin header to the response specifying the requesting origin (or * to allow any origin.)

  • Step 3: browser receives response When the browser sees this response with an appropriate Access-Control-Allow-Origin header, the browser allows the response data to be shared with the client site.

More links

Here is another good answer, more detailed as to what is happening: https://stackoverflow.com/a/10636765/1137669


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...