URL Shortener Microservice - blocked by CORS policy

Hey all,

I’m unable to pass the tests for the URL Shortener Microservice project, even though it works fine when I test it myself.

I get this error message about the access to fetch being blocked by CORS policy, and think it’s likely to be the problem:

Access to fetch at 'https://boilerplate-project-urlshortener-1v2.jesswebber.repl.co/api/shorturl' from origin 'https://www.freecodecamp.org' has been blocked by CORS policy: 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.

Does anyone know how to get round this issue?

I’ve tried a few different things mentioned elsewhere in the forum e.g. tried using a Chrome extension, tried adding an astericks (*) for cors in the code so all websites are allowed, but still can’t solve it. Can anyone help?

Here’s my project code: https://replit.com/@jesswebber/boilerplate-project-urlshortener-1v2?v=1

Thanks!

Did you try just using app.use(cors()) at the top?


Your code is kind of hard to read, for starters, please format it. Repl has a format button on the top right of the code editor. Having functions named app2, app3, and app4 is just a really bad idea. Pretty sure you also have some scope issues (e.g. urlLookup).


The use of a DB makes it a little more cumbersome for other people to test this unless you leak the info so people can just fork it (and then when done revoke it). Otherwise, we have to use our own DB to test with. Which is fine I guess, I’m just not going to do that right now.

1 Like

@lasjorg - yes, I tried using app.use(cors()) at the top, but it still didn’t fix it.

Thanks for the feedback on the code though. Looking at it again, you’re right, it is a bit confusing/hard to read.

Did you remove the other calls to cors?

If I fork you project and remove your cors code and just add app.use(cors()) I do not get any CORS errors for the /api/shorturl path. I would suggest you try removing all other calls to cors.

Remove both calls:

app.use(cors({
  origin: 'https://www.freecodecamp.org'
}));
app.post("/api/shorturl", cors(), (req, res, next) => {

})

Just have app.use(cors()) at the top after the last require.

@lasjorg - I edited the code as you suggested, and I’m still getting the CORS blocked message in the console.
Please could you check the code again to see if I amended it in the way you meant?
Thanks very much

It looks right but I can’t run your repl. I’m getting a 502 (Bad Gateway). Usually, errors like that clear themselves after some time.

I’ve forked and ran your project without the gateway/CORS problems. I added console.log() on all the route inputs and outputs.

Your GET route was not being hit by the tests. There’s an unnecessary ? on the end of the route path. But when it does hit, it throws the error you have set because there are no records in the DB.

Your POST route gets the URL, but it always hits the unable to save to database conditional. If you log the error that catches there to trigger that response, it complains that your short_url is not a number in violation of the schema (I got it to save a URL by hard coding a number). There are packages that provide automatically incrementing integers that handle the short_url bit if you want to use one. Regardless, short_url has to be a number, so you may want to log the value that you’re finding for it to make sure it’s what you think it is. It’s not a number now.

Once the POST route can store URLs, then you need to fix the retrieval in GET. Currently, you’re stringifying and using regexes to search for the URL to redirect, but it’s just the value of the original_url key in the results dictionary (which may or may not be in an array, depending on your use of find() or findOne()).

Finally, you’re bound to hit some weird execution errors if you don’t return your responses from your routes, like return res.json(...). I think I hit several while debugging.

1 Like

Thanks very much @jeremy.a.gray. I edited the code based on your feedback:

  • Removed the unnecessary “?”
  • Changed the short_url so it’s a number
  • Minimised uses of regexes, and took the value from the dictionary instead.

However…I still have the same issue, it’s all working fine when I test the URL myself, but when it I submit it through the FCC page, it only passes the first test. And I’m still getting the Cors error message. This makes me think it’s still something to do with Cors and not the rest of the code.

Will keep looking into it! Any other ideas welcome too.

I don’t see any CORS error when I submit your code. Where exactly are you looking, in the browser (console/network tab) when submitting or what?

Some of the tests did timeout for me. Not sure if it’s just a lack of a return or something else.

On my end, it was timing out, but since chrome’s console never got the appropriate CORS header, it eventually converted the error to a CORS error. Very helpful of it.

The problem is way more trivial and easy to find. I modified your POST route:

app.post("/api/shorturl", (req, res, next) => {
  console.log(req.body);

and got output like

{
  url: 'https://boilerplate-project-urlshortener-1v2-1.jeremyagray.repl.co/?v=1626307950601'
}

and it took me way to long to realize that the tests are posting req.body.url and not req.body.original_url as in your code. You also need to uncomment the dns lookup stuff so your promises will resolve.

1 Like

@jeremy.a.gray " that the tests are posting req.body.url and not req.body.original_url as in your code". Does that mean I need to change the code somehow?

@lasjorg - after I submit the link and right click, then click inspect, I see the error message in the console. Will check returns, thanks

Yes. The response is supposed to contain a key of original_url in the JSON. That doesn’t mean it will be posted to your route that way. You can see the post in the HTML for the example page or look at a request from the fCC tests:

  const res = await fetch(url + '/api/shorturl', {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: `url=${fullUrl}`
  });

So the URL you should handle is in req.body.url.

@jeremy.a.gray - thank you. That was the issue. It has now passed the tests.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.