在 Nginx 配置文件中,你需要在 server
块中添加 Access-Control-Allow-Origin
指令来允许跨域请求
······省略其他······
http {
server {
······省略其他······
location /api/ {
proxy_pass http://192.168.31.111:9000;
# if只能写在location模块当中
if ( $request_method = 'OPTIONS' ){
return 204;
}
}
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,DELETE,PUT,FETCH,PATCH';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
······省略其他······
}
}
在这个配置中:
CORS(Cross-Origin Resource Sharing,跨源资源共享)是一种安全机制,它允许不同源(即不同的协议、域名或端口)之间的网页请求。CORS 配置是服务器端的设置,用于告诉浏览器哪些源可以访问服务器上的资源。
以下是 CORS 配置的一些关键点:
-
Access-Control-Allow-Origin:
- 这个响应头用来指定哪些源可以访问资源。
- 设置为
*
表示允许任何源访问资源(这在开发环境中很常见,但在生产环境中可能不安全)。 - 可以指定具体的源,如
http://example.com
,只允许来自这个源的请求。
-
Access-Control-Allow-Methods:
- 这个响应头用来指定允许的 HTTP 请求方法,如 GET、POST、PUT、DELETE 等。
- 这有助于服务器明确告诉浏览器,对于跨域请求,哪些方法被允许。
-
Access-Control-Allow-Headers:
- 这个响应头用来指定允许在请求中使用的自定义头信息。
- 例如,如果客户端需要发送自定义的认证头
X-Custom-Auth
,则需要在服务器端明确允许。
-
Access-Control-Allow-Credentials:
- 这个响应头用来指定是否允许发送 cookies 和 HTTP 认证信息。
- 默认情况下,CORS 请求不会发送 cookies,除非这个头被设置为
true
。
-
Access-Control-Max-Age:
- 这个响应头用来指定预检请求的结果可以被缓存多久(以秒为单位)。
- 这可以减少对服务器的请求次数,因为浏览器可以使用缓存的预检结果。
-
Access-Control-Expose-Headers:
- 这个响应头用来指定哪些响应头可以被浏览器访问。
- 默认情况下,浏览器只能访问一些简单的响应头,如
Content-Type
和Cache-Control
。
-
预检请求(Preflight Request):
- 对于某些类型的请求(如使用自定义头或非简单请求方法),浏览器会先发送一个预检请求(OPTIONS 请求)到服务器,询问是否可以进行实际的请求。
- 服务器需要在预检请求中返回适当的 CORS 响应头,以允许实际的请求。
CORS 配置的目的是确保网页应用的安全性,同时允许必要的跨源请求。正确配置 CORS 对于开发现代 web 应用非常重要。
OPTIONS的204场景设置?
在 Nginx 中,if
语句通常用于 location
块中,而不是 server
块。if
语句用于根据请求的特定条件来改变处理方式,例如检查请求头或请求方法。由于 server
块主要用于定义服务器级别的配置,如监听端口和服务器名称,因此 if
语句在 server
块中没有意义nginx无法识别。并且if
语句与下一个括号字符之间按照语法需要增加一个空格
以下是 if
语句在 Nginx 配置中的一些使用场景:
-
在
location
块中:if
语句可以在location
块中使用,以根据请求的不同条件来执行不同的操作。location / { if ($request_method = OPTIONS) { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # 其他 CORS 相关的头信息 return 204; } }
-
在
map
指令中:if
语句不能直接放在map
指令中,但map
可以用来创建一个变量,该变量的值取决于条件判断,然后可以在if
语句中使用这个变量。map $http_user_agent $is_mobile { ~*Mobile.* 1; default 0; } if ($is_mobile) { # 针对移动设备的配置 }
-
在
limit_except
块中:if
语句也可以在limit_except
块中使用,通常与location
结合使用来限制特定的请求方法。limit_except POST { if ($request_method = 'OPTIONS') { # 允许 OPTIONS 方法 } }
如果你尝试在 server
块中使用 if
语句,Nginx 可能会报错,因为它不支持在该上下文中使用 if
。确保将 if
语句放在正确的上下文中,如 location
块中,以避免错误。
那么add_header可以写在server块中吗?
是的,add_header
指令可以写在 server
块中,也可以写在 location
块中。当你在 server
块中使用 add_header
指令时,它将对所有通过该服务器处理的请求生效。这意味着这个指令添加的 HTTP 头将被添加到所有响应中,除非你在更具体的 location
块中覆盖它。
下面是一个示例,展示了如何在 server
块中使用 add_header
:
server {
listen 80;
server_name example.com;
# 添加一个通用的响应头
add_header X-Custom-Header "MyValue";
# 其他配置...
}
location / {
# 特定于 location 的配置...
}
在这个配置中,X-Custom-Header
将被添加到所有响应中。如果你需要为特定的 location
添加不同的响应头,你可以在相应的 location
块中再次使用 add_header
指令,它将覆盖 server
块中的设置。
请注意,add_header
指令添加的头信息可以被后续的 location
块中的相同头信息覆盖。因此,如果你希望某些头信息仅应用于特定的请求路径,你应该在对应的 location
块中添加它们。
完整配置参考
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
server {
listen 9000;
server_name localhost;
location / {
try_files $uri $uri/ /index.html /index.htm;
}
location /resources/ {
charset utf-8;
alias F:/;
autoindex on;
}
error_page 500 502 503 504 /50x.html;
location /api/ {
proxy_pass http://192.168.31.111:9000;
if ( $request_method = 'OPTIONS' ){
return 204;
}
}
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,DELETE,PUT,FETCH,PATCH';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
}
}
亲测可用