Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

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

http 跨域,复杂请求的怎么解决

常规情况下跨域,只需要服务端设置响应头 即可

res.header('Access-Control-Allow-Origin', 'http://localhost:3001');  // *

这个情况,普通的get请求已经解决,但是

但在post请求时加之传递数据,此时已经是 非简单请求了

const params = {data: 1};
axios.post("http://localhost:3000/list", params)

应为 content-type: application/json;

这个时候也能通过前端设置请求 header content-type 转成简单请求

axios.post("http://localhost:3000/list", params, {
   headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        // "Authorization": "1231"
      }
    })

但是如果前端自定义header 的 Authorization ,这个时候有出现跨域了;

我的问题是:

  • 怎么保持Content-Type 是application/json;的情况下支持跨域
  • 当头部有自定义字段Authorization时候,怎么跨域

补充:

下面这个配置 对第二个问题无效

  res.setHeader('Access-Control-Allow-Headers', "Authorization");

对option处理


app.all("*", function (req, res, next) {
  res.header(
    "Access-Control-Allow-Headers",
    "Authorization,Accept,Content-Type,Referer,sec-ch-ua,sec-ch-ua-mobile,User-Agent"
  );
  res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
  res.header("Allow", "PUT,POST,GET,DELETE,OPTIONS");
  next();
});


app.post("/list", function (req, res) {
  res.header("Access-Control-Allow-Origin", "http://localhost:3001");
  res.header("Access-Control-Expose-Headers", "Authorization");
  res.header("Content-Type", "application/json;charset=utf-8");

  res.json({
    list: [
      {
        id: 1,
        name: "ranck",
        time: "2020-02-03",
      },
      {
        id: 1,
        name: "ranck",
        time: "2020-02-03",
      },
      {
        id: 1,
        name: "ranck",
        time: "2020-02-03",
      },
    ],
  });
});

option截图

image.png

post 复杂请求截图

image.png

报错截图

image.png


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

1 Reply

0 votes
by (71.8m points)

你既然知道“简单请求”这个术语,那请问你是否知道“非简单请求”会有什么结果呢?看起来你对“简单请求”和“跨域请求”存在了理解偏差。

无论简单请求或非简单请求,都是可以通过设置 CORS header 让浏览器允许跨域请求的。所以你的问题根本就不成立:

  • 怎么保持Content-Type 是application/json;的情况下支持跨域
  • 当头部有自定义字段Authorization时候,怎么跨域

跨域非简单请求只是会额外产生一个 preflight 预检请求,也就是 method 为 OPTIONS 的请求,这个 OPTIONS 请求是规避不掉的,也无需规避,但是你的服务端必须正确响应这个 OPTIONS 请求。

所以答案就是:

Content-Type 为 application/json 以及 带 Authorization 的请求为非简单请求,会额外产生一个 OPTIONS 请求,只要 OPTIONS 请求正确响应,非简单请求也能正常跨域。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...