跨域的时候,post为什么会发送两次请求?

Daotin 于 2024-08-20 发布 编辑

什么是预检请求?

想象你要去一个从未去过的国家旅行。在真正踏上旅程之前,你可能会先打电话给那个国家的海关,问问你是否可以入境,需要带什么证件,是否需要签证等。这个打电话询问的过程,就像是预检请求。

在网络世界中,当你的网页想要访问另一个网站的数据(这就是所谓的跨源请求)时,浏览器有时会先发送一个”预检请求”,就是在问那个网站:”嘿,我可以用这种方式访问你的数据吗?”

预检请求是浏览器在发送实际的跨源请求之前,先向服务器发送的一个特殊的 OPTIONS 请求,用于检查实际请求是否安全可接受。

为什么会有预检请求?

预检请求的存在是为了增加浏览器和服务器之间交互的安全性,防止恶意的跨域请求滥用用户身份信息或对服务器资源造成威胁。这是一种保护机制,确保只有经过服务器许可的跨域请求才会被执行。

哪些情况会发起预检请求?

  • 同源请求:不需要预检,无论请求多么特殊。
  • 跨源请求:可能需要预检,取决于请求的具体特征。

对于同源请求,即使请求很特殊,也不会触发预检请求。这是因为同源策略(Same-Origin Policy)本身就是一种安全机制,浏览器默认信任来自同一源的请求。

比如,

举个具体的例子:

假设你有一个网页游戏,需要向另一个网站的服务器发送玩家的高分数据。

fetch('https://other-website.com/api/scores', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Player-Id': '12345',
  },
  body: JSON.stringify({ score: 1000 }),
});

这个请求会触发预检,因为:

浏览器会先发送一个 OPTIONS 请求(预检请求),询问服务器是否允许这样的请求。如果服务器答应了,真正的 POST 请求才会被发送。