I had my app deployed on VM and it has three api endpoints. when I do post a request to the two of the end points they work pefectly fine. I already have enabled cors for all routes
app.use(cors());
app.post('/api/login')
app.post('/api/autofill')
but for the third api I am getting user inputs from a form and submitting it to the backend. If I attach images along with form inputs it is giving me CORS error. but if I just only send on the datas without any image attachment it works.
app.post('/api/create' , (req, res) => {
res.send(200)
})
No 'Access-Control-Allow-Origin' header is present on the requested resource.
I tried many things and I can't seem to figure out what's causing this problem.
Figured out the answer. the problem was Nginx. Nginx was returning cors error when file size was bigger than the default value it accepts which was 1MB.
corrected it by setting client_max_file_size 100M inside server block in nginx default config.
Related
I have a frontend application built using reactjs and django rest framework is used to serve this frontend using APIs. The django rest APIs are working fine, I have checked via Postman.
When I make a GET request to http://127.0.0.1:8000/articles/, I get the list of articles, and when I click on one of them, it is supposed to take me to the article detail page for that specific id of the article. This is done by making a GET request to http://127.0.0.1:8000/articles/id.
The problem is, when I make GET request for id=2,3,4,5,... , it works fine. But when I try to make a request for id=1, I get the following error at console of chrome browser
Access to XMLHttpRequest at 'http://127.0.0.1:8000/articles/1' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:84)
So, the request is not made at all(I verified from server side). All I get is the above error.
Please note that there is no such error for articles/2 or articles/3 and so on. I have allowed the relevant host in django settings.py file.
This is the code I have for the article detail page.
function ArticlePage(props) {
const [MainArticle, setMainArticle] = useState({});
const {id} = useParams()
const url = 'http://127.0.0.1:8000/articles/'+id;
useEffect(() => {
console.log("hello world");
axios.get(url)
.then((response) => {
setMainArticle(response.data);
console.log(response.data);
})
.catch((error)=>console.log(error))
}, [url]);
return (
<section className="postsBody">
<Article
title={MainArticle.title}
author={MainArticle.author}
timestamp={MainArticle.timestamp}
content={MainArticle.content}
/>
</section>
)
}
Please help me out with this error, via debugging I came to know that the problem is not in the server side, the GET request works for id=1 via postman.
I figured out the problem eventually. The problem is the browser cache. I updated django, djago-rest-framework, react and react-router-dom. Then I did a hard reload of the localhost:3000 website and it eventually started working. The key point is to clear the browser cache just after you add corsheaders and it will work. I took help from this Question
It's because of the CORS policy. Even if you allow the sites in the settings, you need to explicitly enable those websites to access content from your backend. Install cors headers app in Django and set the allowed origins. The documentation for cors headers has sufficient information.
Backend
I am trying make a JWT cookie based authentication work. I am currently performing the following cookie setting as part of a login route in the backend API.
res.cookie('authCookie', token, {maxAge: 900000, httpOnly: true});
Later when I am auth(ing) any other requests, I am reading off of this cookie and testing it in a passport-jwt strategy.
I have gotten this work in postman - when I perform a login and access a secured route - it works perfectly fine + the cookie is also getting set in postman.
Frontend
Now, I am performing the following call stack in the frontend just to test the working,
axios.post("http://localhost:3001/login", logInParams, config)
.then(result => {
// User is logged in so push them to the respective dashboard
console.log(result);
axios.get("http://localhost:3001/user/profile")
.then(result => {
console.log(result);
})
.catch(err => {
console.log(err);
return;
})
})
.catch(err => {
console.log(err)
return;
});
So basically, I log the user in and that works perfectly fine - I am getting a JSON response as intended, but the call is supposed to set a cookie which it is not and hence the next axios.get call is not returning successfully. Though for some reason I see session cookie and a CSRF cookie. Only this authCookie or the jwt-cookie is not getting set.
Some extra details
I am using cors with default parameters - could this be an error of this? Or is there any changes I have to do with axios? I have seen some answers and being new to MERN I don't really understand them. Does someone know about this or have experienced it and solved it?
Are you running the server from a different port than the one that provides the client (i.e: webpack-dev-server running on localhost:3000 and Express server on localhost:3001)? This looks like a same-site cookie issue. In the latest versions of some browsers such as Chrome cookie setting is being blocked when this one comes from a different origin site. This is due to security concerns; you can learn more about same-site cookies here.
The change made in the browsers is related to the default value they give to a cookie policy property called same-site. The old workaround was treating all the cookies from a different origin as None by default, but last year it changed to consider the same-site policy as Lax when no same-site policy was not explicitly provided by the server. This is a desirable behaviour from the browser because it helps at preventing third party sites making use of the cookie provided by the server, but you can edit it by different ways:
Changing the default same-site policy of your browser settings (the article about same site cookies explains).
Sending a same-site:'None' from the server. Express has a way to do so explaind on its docs. Keep in mind browsers also have a new policy to ignore same-site:'None' when the cookie is not marked as Secure, what demands the use of HTTPS (I guess this behaviour can be edited in your browser settings if you want to check while using HTTP).
Obviously, any strategy that demands the users to change their browser settings is a no-go, so running HTTPS with Secure cookies is mandatory for same-site:'None'.
You always have the approach of making both browser and client same origin, so you won't have any issues at all with same-site (i.e. the Express server returning the index.html of the production build of your client as its main static). I haven't found any way to configure CORS module to have a default same site cookies policy (or its sole use as middleware to change it), likely not its purpose, but you can try by adding a dynamic origin config.
As far as I've seen, Postman does not support the same-site cookie property yet, so that would explain why is it working on Postman but not on the browser.
From the looks of it - it seems to be an issue with how cors works and I am adding the following answer to help anyone else coming across it. Thank me later :)
Server Side
You will have a cors in your server that looks like this,
app.use(cors());
You will have to set credentials to true and set the allowedHeaders and origin as follows,
app.use(cors({
credentials: true,
allowedHeaders: ['Content-Type', 'Authorization'],
origin: ['http://localhost:3000']
}));
This is because normally cookies are not allowed to be set in the browser if the server and the client are in the same port. To handle this the above is required on the server side.
Client Side
We also have to pass the cookies when we are sending the request and to do this with axios just add the following in the index.js of your react app as so,
axios.defaults.withCredentials = true;
I think you should write send('cookies are set') at the end in res.cookie('authCookie', token, {maxAge: 900000, httpOnly: true});
I have a react webapp that calls an api (that calls another api using fetch) for image urls and renders the images on the screen through img tags.
The issue I'm having is that the images don't load and instead i get a CORB warning in the console.
Cross-Origin Read Blocking (CORB) blocked cross-origin response
https://website.com
with MIME type text/html. See
https://www.chromestatus.com/feature/5629709824032768 for more
details.
Notice that im having an issue with CORB not CORS A lot of online posts just give the soluton of adding stuff to the headers which may solve CORS issue but i don't believe they solve CORB. In any event, the api i'm using is not mine so i wouldn't be able to add anything server side anyway.
Do i need to add something to my project client side to get this to work? Any ideas would be appreciated.
That happens because the type you requested does not match the data type that is responded from the server. to overcome this try to compare the two. But, if you doesn't have access to target server, You can make a proxy to the destination server. create one more server that will edit the response header from example.com
Example:
Client App => Your proxy server with modified Content-Type header (Ex: http://myproxy.com) => Your destination server (Ex: http://example.com)
Or if you don't want to create a new server and the application is only opened by you personally, you can replace your browser with a version that doesn't yet apply CORBS.
There is no other attempt I know for the client besides that.
Forgive me for the obvious error I am obviously committing...
I understand CORS, how and why it's used. But I'm missing the blindingly obvious in this instance.
I'm trying to access a publicly available API that should work fine (I've been assured)
If I hit the endpoint in Chrome, or in Postman, all works fine: wonderful JSON is returned.
When I try to do the same using axios from within my create-react-app's componentDidMount, I get a CORS error, specifically
Access to XMLHttpRequest at 'http://some-interesting-url/sub-url?blabla=blip&foo=bar' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
What is it I'm failing to grasp? Is there anything I can do from my end? (I have no control over the server)
The Postman app is not a browser so it isn't bound by the rules of CORS. In a browser too, trying to access a URL directly doesn't trigger Cross-Origin-Request-Sharing policies. CORS, by definition will only affects the 'cross-origin' requests made from background JS code of a web-page, to another web-page or API not hosted on same domain name.
Based on the error posted, the API in question is not sending Access-Control-Allow-Origin header. If it's possible to get the API changed, that you should get the header added to response (with value '*', or your domain name). However if that's not possible, then you'd need to route the request through a web-server that you own and include this header there. This kind of does work like a proxy, albeit for a specialized use-case.
If you already have some server side application running, you can simply add another end point to your application. A call to this new end point should trigger the 'Public API' call, and send the response back to client. Since the server side program (eg PHP/Python/NodeJS) would never be a browser, they will not face the CORS issues. If your original web-page is also loaded from same web-server, then the response header can be skipped.
i'm a frontend developer.
i want to get metadata.
so i use the metascraper libraray. ==>https://www.npmjs.com/package/metascraper
it is npm libraray.
but i'm faced with an unexpected difficulty that cors error.
how can i do?
please help me.
Metascraper
.scrapeUrl("http://www.naver.com")
.then((metadata) => {
console.log(metadata)
})
As you don't control the target, the only solution is to proxy the request through your local server.
To do that, you'd create a server side script in something like PHP/Node which takes a URL and does a server-to-server request to get the response and output it. Your Metascraper would call your local server side script, passing the target URL. This would work because server-to-server calls are not subject to CORS.
If you did happen to control the target, then you can output a CORS header (access-control-allow-origin) to disable CORS for everyone or a whitelist of domains.
Could you share the error, that you get in console browser?
I have tried to do the same request to naver.com.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(function(){
$.get('https://www.naver.com/').then(function(response) {
console.log(response);
});
})
</script>
And got the next error:
XMLHttpRequest cannot load https://www.naver.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9080' is therefore not allowed access.
So we can make a conclusion that naver.com server doesn't support CORS.
And there is no problem with library that you are trying to use.