How do I do a CORS on my api?

I noticed that my api is not recieving clientside request and it from something called the Same Origin Policy. I need to implement somthing called a cors. I don’t know how to do this. My api is on a glitch site called message-api

I see you’re using Express. I googled it, and you could try adding something like this in your setup region of server.js:

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

Here’s my source:
https://enable-cors.org/server_expressjs.html

Here’s what I searched online:
https://duckduckgo.com/?q=express+allow+cross+origin+&t=ffab&ia=web

Looking at your code, I think you could insert the code above at line 18 of server.js before your server.listen

Hope it helps - let us know!

2 Likes

Um. I still have errors.
Failed to load https://message-api.glitch.me/login: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://spark-roof.glitch.me' is therefore not allowed access. The response had HTTP status code 404.

script.js:10 Cross-Origin Read Blocking (CORB) blocked cross-origin response https://message-api.glitch.me/login with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details.

I think the problem is in the order you’re adding your Express middleware. If the route that’s requiring CORS is defined along with your other routes in api/routes/route.js then the app.use call with the CORS definitions needs to come before where the routes are defined (so right after https://glitch.com/edit/#!/message-api?path=server.js:12:0).

https://message-api.glitch.me/login

script.js:10 OPTIONS https://message-api.glitch.me/login 404 (Not Found) (anonymous) @ script.js:10 spark-roof.glitch.me/:1 Failed to load https://message-api.glitch.me/login: Response for preflight has invalid HTTP status code 404.
Now the cors error gone. What this mean? It’s on a thing called spark-flow that im testing

Ok. I’m getting an options error… . . .

That url (https://message-api.glitch.me/login) as well as the root url (https://message-api.glitch.me/) are both returning 404 status codes, which is why the OPTIONS call is also doing the same. That’s probably because you’re only accepting POSTs to that path in api/routes/route.js (on line 47).

I’m sending a POST in spark-roof:

let xhr = new XMLHttpRequest()
xhr.open("POST", 'https://message-api.glitch.me/login')
xhr.setRequestHeader('Content-Type', "application/json");
xhr.onreadystatechange = () => {
    if (xhr.status == 200) {
        alert('Reqest succeeded');
    }
    console.log(xhr)
}
xhr.send(JSON.stringify({
    usrnm:'Example Username', 
    psw:'Example Password'
}))

The pre-flight request for CORS sends an OPTIONS request, so when CORS executes it’s getting a 404 from the pre-flight because you’re not handling the OPTIONS method.

My suspicion is that you’ll want to respond to the OPTIONS request appropriately. https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request might be useful for understanding what’s going on between the two projects, and http://johnzhang.io/options-request-in-express gives some pointers to handling OPTIONS (and specifically CORS) with Express.

2 Likes

Using the magic of your help, I got it working. Thanks, cori! Happy glitching!

1 Like

Here’s how I fixed it for my api node server project on glitch:

1. Open Terminal

2. Install fastify-cors

$ npm i -D fastify-cors

3. Register the fastify-cors plugin.

fastify.register(require('fastify-cors'), { 
  origin: ["https://glitch.com", /localhost\:8080/, "https://example.com"]
});

See fastify-cors docs for more details on setting origin

4. Bonus:

If you don’t want to be able to access it directly in the browser (in other words, restrict it so only your site can use it), you can add some logic in your responses like this, for example:

fastify.get("/my-endpoint", async (request, reply) => {
  const { query = {} } = request;
  let allowed = ["https://glitch.com/", "http://localhost:8080/", "https://example.com/"]; // the ending "/" is important!
  if (allowed.indexOf(request.headers.referer) !== -1) {
    return { myRealResponse: {} }; // Send your real response
  } else {
    return {}; // Just send an empty JSON
  }
});
2 Likes