泸州市网站建设_网站建设公司_Sketch_seo优化
2025/12/25 15:03:08 网站建设 项目流程

浏览器的安全机制(同源策略与CORS)

  • 当用户在当前页面通过 JavaScript 发起一个 AJAX 请求时,请求的协议、域名或端口,任一与当前页面不同,即为跨域请求。
    • 跨域请求是由浏览器发起的(浏览器向第三方服务器发起请求)
  • 浏览器检查CORS响应头:如果请求跨域,浏览器会检查 CORS(跨域资源共享) 机制,然后决定是否允许该请求。
  1. 浏览器检测跨域:浏览器检测到请求跨域后,根据请求类型(简单请求或复杂请求)决定是否发起 OPTIONS 预检请求。
  2. 服务器响应 CORS 规则:服务器通过 CORS 响应头(如 Access-Control-Allow-Origin)告知浏览器是否允许跨域请求。
  • 浏览器阻止了跨域请求:如果浏览器没有检查到 CORS 响应头或者配置不正确,浏览器会认为服务器不允许跨域请求,从而根据浏览器的安全机制(同源策略) 拦截 所有跨域请求,并抛出跨域错误(如 CORS policy 错误)。

CORS(跨域资源共享,Cross-Origin Resource Sharing)机制是由浏览器和服务器共同协作实现的。它的核心目的是在保证安全的前提下,允许浏览器向不同源的服务器发起跨域请求。

OPTIONS 预检请求

在跨域资源共享(CORS,Cross-Origin Resource Sharing)机制中,浏览器为了安全考虑,在发送某些类型的跨域请求之前,会先发送一个 OPTIONS 请求,这个请求被称为 预检请求(Preflight Request)。预检请求的主要目的是确认服务器是否允许实际的跨域请求。

1. 为什么需要预检请求?

  • 安全性:确保服务器明确允许来自特定源的跨域请求,防止潜在的安全风险。
  • 复杂请求:对于一些复杂的 HTTP 请求(如使用了自定义头或非简单方法),浏览器会自动发起预检请求以确保服务器支持这些操作。

2. 哪些请求会触发预检请求?

预检请求通常会在以下情况下触发:

  • 使用了 HTTP 方法(如 PUT, DELETE, PATCH 等)而不是简单的 GETPOST
  • 请求头中包含了非简单头(如 Content-Type 不是 application/x-www-form-urlencoded, multipart/form-data, 或 text/plain)。
  • 使用了自定义请求头(如 Authorization)。

3. 预检请求的工作流程

  1. 客户端发送 OPTIONS 请求

    • 浏览器自动发送一个 OPTIONS 请求到目标服务器。
    • 请求头中包含 Access-Control-Request-MethodAccess-Control-Request-Headers,用于告知服务器即将发送的实际请求的方法和自定义头。
  2. 服务器响应预检请求

    • 服务器根据配置返回相应的 CORS 响应头。
    • 如果服务器允许该跨域请求,则返回状态码 200204,并设置必要的 CORS 响应头。
    • 如果不允许,则返回适当的错误信息。
  3. 客户端发送实际请求

    • 浏览器收到预检请求的成功响应后,才会发送实际的跨域请求。

Nginx 跨域配置

以下是一个典型的 Nginx CORS 配置示例:

location /api/ {# 允许特定源跨域访问add_header 'Access-Control-Allow-Origin' 'http://example.com';                  // 代理的服务器域名和端口号add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With';add_header 'Access-Control-Allow-Credentials' 'true';# 对于OPTIONS预检请求,直接返回204if ($request_method = 'OPTIONS') {return 204;}proxy_pass http://192.168.1.1:2443; //代理的服务器url
}
  • add_header 指令:用于设置 CORS 相关的响应头。

    • Access-Control-Allow-Origin:指定允许跨域访问的源(如 http://example.com*)。
    • Access-Control-Allow-Methods:指定允许的 HTTP 方法(如 GET, POST, PUT 等)。
    • Access-Control-Allow-Headers:指定允许的请求头(如 Content-Type, Authorization 等)。
    • Access-Control-Allow-Credentials:指定是否允许携带凭证(如 Cookies)。
  • if ($request_method = 'OPTIONS') { return 204; }:当请求方法为 OPTIONS 时,直接返回状态码 204 No Content,表示预检请求成功,但不返回任何内容。这可以避免不必要的处理逻辑,提高性能。

add_headeralways 作用

在 Nginx 中,add_header 指令用于向 HTTP 响应中添加自定义的响应头。默认情况下,add_header 只在响应状态码为 时生效。如果需要对所有响应状态码(包括错误状态码如)都添加响应头,可以使用 always 参数。

location /api/ {add_header 'Access-Control-Allow-Origin' 'http://example.com' always;add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;return 404;
}

1. 默认行为(无 always

  • 默认情况下,add_header 只在成功响应(200, 201, 204, 206, 301, 302, 303, 304, 307, 或 308)时添加响应头。
  • 对于错误响应(4xx5xx),add_header 不会生效。

2. 使用 always 参数

  • 如果添加了 always 参数,add_header 会在 所有响应状态码 下生效,包括错误状态码(如 4xx5xx)。
  • 这在需要为所有响应(包括错误响应)添加特定响应头时非常有用。

nginx #跨域请求

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询