编辑
2023-09-23
后端
00
请注意,本文编写于 595 天前,最后修改于 595 天前,其中某些信息可能已经过时。

目录

什么是浏览器同源策略?
什么是预请求?
总结
实践,gin设置支持跨域请求

什么时候POST请求会发送两次?

以下是可能导致POST请求发送两次的一些原因:

  1. 重复提交:用户可能在提交表单或发送POST请求时多次点击提交按钮或发送请求的操作,导致请求被发送多次。

  2. 页面刷新:当用户在提交POST请求后刷新页面时,某些浏览器会尝试重新发送之前的POST请求,以便用户可以重新加载页面并继续之前的操作。

  3. 跨域请求:在某些情况下,如果你的网页中存在跨域请求,浏览器可能会发送OPTIONS请求进行预检(preflight),然后再发送实际的POST请求。这样就会导致看起来像是发送了两次POST请求,但实际上第一个请求是OPTIONS请求。

  4. 重定向:如果服务器返回一个重定向响应(例如状态码为302),浏览器可能会自动跟随重定向并发送第二个POST请求。

  5. 缓存问题:一些缓存机制可能会导致POST请求被重复发送。例如,浏览器或代理服务器可能会缓存POST请求的响应,然后在后续请求时重用缓存的响应,从而导致看起来像是发送了两次POST请求。

以下是一些常见的解决方法:

  • 在前端代码中,可以通过禁用提交按钮或在提交请求后禁用表单来防止用户多次点击提交按钮。
  • 在服务器端,可以使用幂等性来处理重复请求,确保多次相同的POST请求不会产生不一致的结果。
  • 如果是跨域请求导致的问题,可以在服务器端进行相应的配置,允许跨域请求或使用CORS(跨源资源共享)机制进行处理。
  • 如果是缓存问题,可以在服务器端设置适当的缓存控制头,以确保POST请求不会被缓存或缓存的时间较短。

根据具体的情况,你可能需要进一步调查并采取适当的解决措施来处理重复发送的POST请求。

什么是浏览器同源策略?

同源策略(Same-Origin Policy)是一种浏览器安全机制,用于限制在浏览器中加载的网页脚本与来自不同源(即不同的域、协议或端口)的资源之间的交互操作。它是为了保护用户的隐私和安全而设计的。

同源策略的基本原则是,当一个网页脚本尝试访问另一个源的资源时,浏览器会阻止这种跨源的操作,以防止恶意网站利用跨域请求获取用户的敏感信息或对其他网站进行攻击。

同源策略的限制主要包括以下几个方面:

  1. 域名:同源策略要求两个网页具有相同的域名(协议、主机和端口),即使两个域名只是在协议、主机或端口上稍有不同,也会被视为不同源。例如,http://example.comhttps://example.com 被视为不同源。

  2. Cookie、LocalStorage 和 IndexDB:同源策略限制了对跨源的 Cookie、LocalStorage 和 IndexDB 的访问。这意味着网页脚本只能访问属于同一源的 Cookie 和存储数据,而无法读取或修改其他源的数据。

  3. DOM 访问:同源策略限制了对跨源文档对象模型(DOM)的访问。网页脚本只能修改属于同一源的 DOM 元素,无法直接访问或修改其他源的 DOM。

  4. XMLHttpRequest 和 Fetch 请求:同源策略对跨源的 XMLHttpRequest 和 Fetch 请求进行限制。通常情况下,这些请求只能向同源发起,无法直接访问其他源的数据。

为了允许跨域请求,浏览器引入了一些机制,如跨域资源共享(CORS)和服务器代理。这些机制允许服务器通过设置适当的响应头来授权特定的跨域请求。

同源策略在保护用户隐私和安全方面起着重要的作用,防止恶意网站滥用用户的信息。然而,有时候需要进行跨域操作,因此开发人员需要了解和遵守跨域规则,并使用适当的跨域解决方案。

什么是预请求?

预请求(Preflight Request)是在进行跨域资源共享(CORS)时,某些特定情况下由浏览器自动发送的一种HTTP请求。它是一个OPTIONS请求,用于在实际的跨域请求之前进行预检,以确定是否允许实际请求的发送。

在以下情况下,浏览器会发送预请求:

  1. 跨域请求:当浏览器发起跨域请求时,即请求的目标与当前页面的域名、协议或端口不一致时,浏览器会发送预请求。

  2. 自定义请求头:如果在跨域请求中使用了特定的自定义请求头(例如Content-TypeAuthorization等),并且这些请求头属于 "CORS安全列表" 之外的请求头,浏览器也会发送预请求。

预请求的目的是为了确保服务器支持跨域请求并允许浏览器发送实际的跨域请求。预请求的发送和处理过程如下:

  1. 发送预请求:浏览器在发送实际的跨域请求之前,先发送一个OPTIONS请求,其中包含了一些额外的头部信息,如Origin(指示请求的源)和Access-Control-Request-Method(指示实际请求的方法)等。

  2. 服务器处理预请求:服务器接收到预请求后,进行预检查。它会检查请求的源是否在允许的跨域列表中,以及是否允许实际请求的方法、请求头等。

  3. 响应预请求:服务器根据预检查的结果,返回包含了对应的响应头信息的响应。响应头中重要的字段是Access-Control-Allow-Origin(指示允许的源)和Access-Control-Allow-Methods(指示允许的方法)等。

  4. 浏览器处理预请求响应:浏览器接收到预请求的响应后,会检查响应头中的相关字段,以确定是否允许发送实际的跨域请求。

  5. 发送实际请求:如果预请求的响应表明服务器允许实际请求,浏览器会发送实际的跨域请求,其中包含了实际的请求方法、请求头等。

需要注意的是,预请求是由浏览器自动发送的,并且在实际请求之前进行。它的目的是为了提供一种机制,确保服务器允许跨域请求,以增加安全性。服务器需要正确地处理预请求并返回适当的响应头,以允许或拒绝实际的跨域请求。

总结

预请求就是浏览器在进行跨域请求访问时向目标浏览器发送的一个预检测请求,检测目标服务器是否支持跨域请求,预请求是一个OPTIONS请求,其中包含了一些额外的头部信息,如Origin(请求源)、Access-Control-Request-Method(实际请求的方法)和Access-Control-Request-Headers(实际请求的头部信息)。服务器收到预请求后,可以检查这些头部信息,并决定是否允许实际的跨域请求。

服务器在收到预请求后,可以通过设置响应头部中的Access-Control-Allow-Origin、Access-Control-Allow-Methods和Access-Control-Allow-Headers等字段来指定允许的跨域请求来源、方法和头部信息。如果服务器确认允许跨域请求,浏览器会继续发送实际的跨域请求,否则将阻止实际请求的发送,并返回相应的错误。

预请求机制的目的是确保服务器允许跨域请求,并在发送实际请求之前进行验证,从而保护用户的隐私和安全。开发人员需要在服务器上正确地配置CORS头部信息,以便处理预请求,并允许必要的跨域请求。

实践,gin设置支持跨域请求

1.通过自定义中间件

package main import ( "github.com/gin-gonic/gin" ) func main() { // 创建 Gin 引擎 router := gin.Default() // 添加跨域请求的中间件 router.Use(corsMiddleware()) // 添加你的路由处理逻辑 // 启动服务器 router.Run(":8080") } // 跨域请求中间件 func corsMiddleware() gin.HandlerFunc { return func(c *gin.Context) { // 设置允许的请求来源 c.Writer.Header().Set("Access-Control-Allow-Origin", "http://example.com") // 设置允许的请求方法 c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE") // 设置允许的请求头部信息 c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") // 设置是否允许发送凭据 c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") // 如果是预请求(OPTIONS请求),则直接返回 if c.Request.Method == "OPTIONS" { c.AbortWithStatus(204) return } // 继续处理实际的请求 c.Next() } }

2.官方推荐跨域请求中间件,具体可以看官方示例代码

本文作者:yowayimono

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!