Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

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

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

Open
Daotin opened this issue Aug 20, 2024 · 0 comments
Open

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

Daotin opened this issue Aug 20, 2024 · 0 comments

Comments

@Daotin
Copy link
Owner

Daotin commented Aug 20, 2024

什么是预检请求?

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

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

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

为什么会有预检请求?

  • 安全考虑:就像国家要控制谁可以入境一样,网站也需要控制谁可以访问它们的数据。
  • 保护隐私:预检请求不会包含实际的数据,就像你打电话询问入境要求时,不需要提供你的全部个人信息。
  • 避免麻烦:如果直接发送可能不被允许的请求,就像直接飞到一个国家却被拒绝入境,这样会很麻烦。

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

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

Tip

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

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

比如,

  • 使用特殊的"旅行方式":如果你想骑大象入境(比喻使用 PUT, DELETE 等特殊的 HTTP 方法),而不是普通的步行(GET, POST),海关可能会要求你提前通知。
  • 携带特殊物品:如果你想带一些特殊的物品入境(比如使用自定义的 HTTP 头部,例如,自定义的X-Custom-Header或Authorization ),也需要提前询问。
  • 特殊的行李包装:如果你的行李包装方式很特别(比如,如果Content-Type请求头的值不是以下三种之一,application/x-www-form-urlencodedmultipart/form-datatext/plain,比如发送 application/json 数据),也可能需要预先检查。

举个具体的例子:

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

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

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

  • 它使用了自定义头部(X-Player-Id)
  • 它发送的是 JSON 数据

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant