相关文章推荐
刚毅的海龟  ·  426 Upgrade Required ...·  2 月前    · 
犯傻的水桶  ·  Riverside: HD Podcast ...·  11 月前    · 
豪爽的菠萝  ·  python自定义包代码转 ...·  2 年前    · 
飘逸的山羊  ·  New DS 3 shown with ...·  2 年前    · 
文质彬彬的手套  ·  Pandas ...·  2 年前    · 

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I'm putting together an API with warp, and I'm trying to make it so that certain data can be requested cross-origin via POST. However, as soon as I add .and(warp::body::json()) to the filter, CORS stops working. I am testing CORS by going to http://example.com and issuing fetch() calls with http://127.0.0.1:8081 as URL from JavaScript via Firefox' developer tools. It may be me doing something wrong here, but should that be the case I don't understand what it might be.

Code snippet where CORS does not work even though I imagine it should:
not-working.zip

Code snippet where CORS does work as I imagine it should:
working.zip

Adding .and(warp::body::json()) causes cors to stop working Adding .and(warp::body::json()) causes CORS to stop being allowed Jun 20, 2020

Oh you just need to tell cors to allow the content-type header, because we are using the json body, like this:

let cors = warp::cors()
        .allow_methods(&[Method::POST])
        .allow_header("content-type");

If you get this error in the browser console:

SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data

That's just because the response data wasn't json, but the request did work.

Oh you just need to tell cors to allow the content-type header, because we are using the json body, like this:

let cors = warp::cors()
        .allow_methods(&[Method::POST])
        .allow_header("content-type");

Could you apply this to the code in not-working.zip and re-send it? I tried doing it like you proposed here but the result stays the same.

This is the code I ran:

fetch("http://127.0.0.1:8081/apples", {method: "POST", body: JSON.stringify({num: 25})})

I ran it in the browser's development tools on http://example.com

Try adding this header to fetch:

fetch("http://127.0.0.1:8081/apples", {
  method: "POST",
  body: JSON.stringify({num: 25}),
  headers: {"Content-type": "application/json; charset=UTF-8"}

Try adding this header to fetch:

fetch("http://127.0.0.1:8081/apples", {
  method: "POST",
  body: JSON.stringify({num: 25}),
  headers: {"Content-type": "application/json; charset=UTF-8"}

That did the trick! Thank you. I'm thinking it might be worth noting something about CORS and headers in the documentation though as I (and seemingly 3 other people) also seem to have ran into this, but I'm not sure how this would be formulated. Not only that, but I would argue this is inconsistent with how the API works in general, as at least in some other cases it is only required that you to specify what's allowed as a way to disallow others (such as with allow_origin(), see #614).

Question is then whether to let that be a separate issue or convert this one.

I was running into this while trying to hit a warp endpoint defined like this:

let cors = warp::cors()
        .allow_any_origin()
        .allow_headers(vec!["content-type"])
        .allow_methods(&[warp::http::Method::GET, warp::http::Method::POST]);
warp::path!("v1" / "redacted")
        .and(warp::get())
        .and(warp::body::json())
        .and_then(handlers::get_redacted_v1_handler)
        .with(warp::log("routes"))
        .with(cors)
        .recover(error::recover);

While using axios like this:

	const URL = `${process.env.BACKEND_URL}/v1/redacted`;
	return axios
		.request({
			method: "GET",
			url: URL,
		.then(response => {
			console.log(`< ${response.status} GET ${URL}`);

Changing warp::get() to warp::post() and axios method: "GET" to "POST" had no change... but then changing the axios side to the following fixed my issue.

return axios
		.request({
			method: "POST",
			url: URL,
			data: {
				'myjsonkey': "myjsonstring",
			headers: {
				"Content-type": "application/json; charset=UTF-8",

I'm not quite sure where the issue is as hitting my warp endpoint from Postman was working fine. But I very specifically had to do the above. Even omitting the data:{ } section of my axios request causes CORS issues, where instead I'd expect a 400 with: Request body deserialize error: EOF while parsing a value at line 1 column 0