Nginx的跨源/跨域配置宏cors_params

网上搜到的很多Nginx CORS配置虽然也起作用,但是可能因未参考规范而缺少基本的逻辑判断,不能表达CORS的工作原理。

Tomcat中有参考自CORS specification的CORS实现CorsFilter,用起来非常方便,故我想把Tomcat CorsFilter的逻辑照搬到Nginx中。

Nginx的if指令不支持逻辑与而导致多条件判断非常吃力,加之If is Evil… when used in location context,因此这里没有完全照搬,只作了基本的逻辑判断。

# nginx cors_params
# Usage:
# put: put this file under nginx’s conf directory, e.g. /etc/nginx/
# include: in your nginx site's 'location' block, add 'include /etc/nginx/cors_params;'
# customize: customize cors options
# 
# Reference:
# [Tomcat CorsFilter](https://github.com/apache/tomcat/blob/master/java/org/apache/catalina/filters/CorsFilter.java)
# [Example Nginx CORS configuration](https://gist.github.com/Stanback/7145487)
#
# cors options
# set allowed_origins below, since regex cannot be written as a variable
set $allowed_methods "GET,POST,PUT,DELETE,PATCH,HEAD";
set $allowed_headers "authorization,x-requested-with,accept,content-type,content-length,range,if-range";
set $support_credentials "";         # "true" or empty string
set $preflight_maxage "60";          # seconds or empty string
set $exposed_headers "content-type,content-length,last-modified,content-range";

set $x "";
if ($http_origin != "") {
  set $x "${x}p"; # p: header Origin is present
}
if ($http_origin != "$scheme://$http_host") {
  set $x "${x}d"; # d: header Origin is different from current origin
}
if ($http_origin ~ "^https?://(localhost|[a-z0-9-.]+\.example\.com)(:\d+)?$") { # allowed_origins
  set $x "${x}a"; # a: header Origin is allowed
}

set $p "";
if ($request_method = "OPTIONS") {
  set $p "${p}o"; # o: method is OPTIONS
}
if ($http_access_control_request_method != "") {
  set $p "${p}r"; # r: header Access-Control-Request-Method is present
}

set $cors "";
if ($x = "pda") {
  set $cors "${cors}x"; # x: cross-origin
}
if ($p = "or") {
  set $cors "${cors}p"; # p: preflight
}

if ($cors = 'xp') {
  # handle cors preflight request
  add_header "Access-Control-Allow-Origin" $http_origin always;
  add_header "Access-Control-Allow-Credentials" $support_credentials always;
  add_header "Access-Control-Allow-Methods" $allowed_methods always;
  add_header "Access-Control-Allow-Headers" $allowed_headers always;
  add_header "Access-Control-Expose-Headers" $exposed_headers always;
  add_header "Access-Control-Max-Age" $preflight_maxage always;
  return 200;
}
if ($cors = "x") {
  # handle cors request
  add_header "Access-Control-Allow-Origin" $http_origin always;
  add_header "Access-Control-Expose-Headers" $exposed_headers always;
}

你可能感兴趣的:(Server-end)