这是博主自用的一套方法,理论上与 Nginx 通用
⚠️ 注意:本方法仅适用于 Nginx 以及 OpenResty,Apache 无法使用。
参考时间:以此文章最后编辑时间为准
系统环境:Ubuntu 20.04.1 LTS
发包程序:OpenResty 1.21.4 (Nginx 1.21.4核心)
什么是 OpenResty?
OpenResty 是一个这是一个由社区开发并维护的基于 Nginx 的高性能 Web 平台,但不完全等同于 Nginx。它集成了 Nginx 和 LuaJIT(一个高性能的 Lua 解释器) 以及许多第三方模块和库。这些模块和库提供了比标准 Nginx 更强大的功能,主要在处理动态内容和扩展的能力上,可以实现高效的 Web 应用程序。
相关链接:
什么是跨域请求?
跨域请求是指当浏览器在一个网页中向不同域名、协议或端口的服务器发送请求时发生的行为。跨域请求涉及的“域”指的是网页的来源,它由 协议(protocol)、域名(domain)、和 端口(port) 组成。
默认情况下,跨域请求的限制来源于浏览器的同源策略。这是是一种安全机制,用于防止网页上的恶意脚本对不同域的资源进行未经授权的访问。通过限制跨域请求可以帮助保护用户数据的安全性和隐私。
那些情况下可以允许跨域?
以下是可能包含的场景,我的使用场景主要是用于跨站资源共享的,一般情况下出于安全考虑请勿允许跨域请求。
- 前后端分离的应用架构
- 跨站点资源共享
- 单点登录(SSO)和身份验证
- 微服务架构
- 前端请求第三方服务
- 跨域请求中的 WebSocket 连接
配置代码 - Nginx
# 指定允许的跨域方法(出于安全考虑,需谨慎设置)
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, DELETE, PUT";
# 预检命令的缓存时间(如果不缓存每次访问都会发送两次请求)
add_header Access-Control-Max-Age 3600;
# 不允许带 Cookie 的请求(布尔值,出于安全考虑默认不允许)
add_header Access-Control-Allow-Credentials false;
# 允许跨域请求的来源(动态获取客户端请求的域名,需谨慎使用)
add_header Access-Control-Allow-Origin $http_origin;
# 指定允许的请求头字段(此处为动态设置允许的请求头字段,可根据需求替换)
add_header Access-Control-Allow-Headers $http_access_control_request_headers;
# 处理 OPTIONS 预检请求
if ($request_method = OPTIONS) {
return 200;
}
重点设定解释:
常见的跨域方法:
- GET:请求从服务器获取数据或资源。GET 请求通常用于获取静态内容,例如 HTML 页面、图像、CSS 文件、JavaScript 文件等。GET 请求不应该对服务器的数据进行任何修改。
- POST:向服务器提交数据,通常用于创建新的资源。POST 请求可以将数据发送到服务器,例如表单提交或上传文件等。POST 请求可以修改服务器上的数据。
- PUT:向服务器上传一个新的资源,或者替换服务器上的一个资源。PUT 请求常用于更新现有资源的内容。
- DELETE:请求服务器删除指定的资源。DELETE 请求通常用于删除数据库中的记录或文件系统中的文件。
- OPTIONS:用于检查服务器支持哪些 HTTP 方法,以及服务器的其他 CORS 设置。浏览器在发送跨域请求之前会发送 OPTIONS 预检请求,以确定服务器是否允许跨域请求。
- PATCH:用于对服务器上的资源进行部分修改。不同于 PUT,PATCH 请求只更新部分资源,而不是替换整个资源。
- HEAD:与 GET 请求类似,但服务器只返回响应头而不返回响应体。HEAD 请求常用于检查资源的元数据(例如响应头中的 ETag 或 Content-Length)。
允许跨域请求的来源:
上方代码的示范是默认允许所有来源的,如果出于安全考虑,可以限定一个或多个域名,具体的代码如下:
# 单域名限定
# 替换项:允许跨域请求的来源(此处允许例如来自 example.com 的请求)
add_header Access-Control-Allow-Origin "https://example.com";
# 多域名限定(使用 if 语句来动态设置响应头)
# 替换项:允许跨域请求的来源(此处允许例如来自 https://example.com 和 https://another-example.com 的请求)
set $cors_origin "";
if ($http_origin = 'https://example.com') {
set $cors_origin $http_origin;
}
if ($http_origin = 'https://another-example.com') {
set $cors_origin $http_origin;
}
add_header 'Access-Control-Allow-Origin' "$cors_origin" always;
指定允许的请求头字段:
上方代码前提是你信任客户端发送的所有请求头。如果想要更加严格,可以指定明确的请求头字段:例如下方代码:
# 替换项:指定允许的请求头字段
add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With";
可根据需求自定义的项目:
- Content-Type:指定请求体的媒体类型。常用于指定数据格式,如 application/json、application/x-www-form-urlencoded、multipart/form-data 等。
- Authorization:用于携带身份验证凭证,如 JWT 令牌或 Basic Auth 信息。用于需要身份验证的 API 请求。
- X-Requested-With:用于标识 XMLHttpRequest(AJAX)请求。常用来在客户端和服务器之间区分普通请求和 AJAX 请求。
- Accept:指定客户端接受的响应内容类型,例如 application/json、text/html 等。
- Origin:指示请求的来源(域)。浏览器自动添加的,服务器可以使用它来判断是否允许请求来源。
- Access-Control-Request-Method:用于预检请求中,表明实际请求将使用的 HTTP 方法(如 GET、POST)。
- Access-Control-Request-Headers:用于预检请求中,表明实际请求将包含的自定义请求头列表(例如 Content-Type、Authorization 等)。
- Accept-Language:指示客户端的语言偏好,用于内容协商。
- Cache-Control:控制缓存行为,用于优化请求和响应的性能。
- User-Agent:标识请求的客户端软件,例如浏览器或其他 HTTP 客户端工具。
食用方法:
将设定好的代码插入到 Nginx 的配置文件中就行了
# 示范的 Nginx 配置
server
{
listen 80;
server_name localhost;
# << 把跨域代码放在这个位置
location / {
# 此处省略一堆代码
}
}
⚠️ 如果你喜欢这篇文章,可以将本文链接收藏起来,请勿直接照搬此文章内容,如需转载请标注来源,这是对博主最大的尊重,谢谢!
Q.E.D.