以下是gist.github.com支援reverse proxied APIs的範例:
2 T# r* k5 M2 a) p- |9 F4 M7 q+ l- m/ ^& n
7 A q" [6 R$ Y$ \% W, w# CORS header support
- T3 G" y8 n4 A: e; T9 U. c#5 l0 M. G( D7 z, I* x6 k
# One way to use this is by placing it into a file called "cors_support"
: ^5 B& }, h- M# [# under your Nginx configuration directory and placing the following
4 E/ e$ X) k1 {3 y% o8 v# statement inside your **location** block(s):' {! r$ h! o) S7 o) ?% A
#. z9 m0 `7 l2 A E% R6 T8 w8 q
# include cors_support;
. K7 e0 P+ p: a2 _. \#
: Y* s% q- D) w( S" ^( N# As of Nginx 1.7.5, add_header supports an "always" parameter which: j9 P+ R9 r3 _1 o$ X
# allows CORS to work if the backend returns 4xx or 5xx status code.( {3 {1 D# u7 |
#: n# m1 ^& K% `. `4 L% Q
# For more information on CORS, please see: http://enable-cors.org/) B/ \5 ]) v$ l) Z# |
# Forked from this Gist: https://gist.github.com/michiel/1064640
7 Z w0 `7 r0 d; D3 u2 E#" N6 d R- l8 k" O
# \1 j/ }3 ^. A/ I7 W
set $cors '';
, O. P. G4 m8 h! C4 Lif ($http_origin ~ '^https?://(localhost|www\.yourdomain\.com|www\.yourotherdomain\.com)$') {% |+ n7 N- ]+ S) y, Z: b; u
set $cors 'true';6 { E( {" h- S9 Q+ N
}
3 v$ {: |, D( i! l9 G0 l1 b% k1 m' b' h2 C' m* u+ y
if ($cors = 'true') {( L e' U% _4 [% A8 t$ w
add_header 'Access-Control-Allow-Origin' "$http_origin" always;5 c. E& C' F. |3 {1 u
add_header 'Access-Control-Allow-Credentials' 'true' always;7 o u! q2 r5 r# u: m
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;7 [8 I( @. d1 Y4 Z) y4 L1 o ?
add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;
' S+ n6 V0 Y) [5 _ # required to be able to read Authorization header in frontend" v7 d$ U6 l, `, Q0 q9 L' B! p, W
#add_header 'Access-Control-Expose-Headers' 'Authorization' always;( t5 T9 i4 i k" ]8 A
}) Q' {% ]: m) X
4 d& {8 b! b3 \; B! l8 t5 ?" P8 mif ($request_method = 'OPTIONS') {
7 O# ?8 b2 D# c5 \ # Tell client that this pre-flight info is valid for 20 days
# J2 I+ X( t% o0 _- i add_header 'Access-Control-Max-Age' 1728000;
& Y+ w. r* @" t+ S add_header 'Content-Type' 'text/plain charset=UTF-8';
9 g3 m4 \) |% v& k' h# a2 ?* ] add_header 'Content-Length' 0;, P, I) @+ l4 k r- ]5 x. f
return 204;$ H0 o; K( R9 g: j: [( T
} https://gist.github.com/Stanback/7145487#file-nginx-conf 的討論範例:
7 o; Q1 l4 K" c& [if ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { return 444;
' D7 J! O8 \$ F$ b}" H) ?! I7 D. d
set $origin $http_origin;. D: j h3 ]4 d+ c
if ($origin !~ '^https?://(subdom1|subdom2)\.yourdom\.zone$') {' ], r0 N a; f, `# n) y: g
set $origin 'https://default.yourdom.zone';
7 g8 `9 y$ _/ }2 F4 j/ c) @$ N. Q}
5 h" q g3 A _" D% v/ [8 vif ($request_method = 'OPTIONS') {& G6 m! @9 y0 O" W! o
add_header 'Access-Control-Allow-Origin' "$origin" always;
2 X# S. e* e9 @6 i" N% ^ add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always; j3 _5 b5 u; z& `3 T/ e7 Z5 f
add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always;! b9 w* Y, D0 p2 j3 J% y
add_header 'Access-Control-Allow-Credentials' 'true' always;6 B$ \& @- x$ t, B+ a. V z
add_header Access-Control-Max-Age 1728000; #20 days
8 u: S. w$ f0 F4 Q9 f add_header Content-Type 'text/plain charset=UTF-8';
$ m# Q+ z, D; I3 N s! V7 h9 F7 W% | add_header Content-Length 0;/ d5 d/ D+ H8 l" D/ T
return 204;& q6 ?5 x- o$ }4 v
}
3 f+ s' N& o* o2 j1 Hif ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') {
9 z& b9 H+ \5 z4 m+ C& S9 R5 @ add_header Access-Control-Allow-Origin "$origin" always;
' s2 g0 Q* v1 @% r! s add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
8 L2 I# a8 R9 k- ^/ W& b0 J7 V add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always;
4 i( ~( @" P7 K/ @& ~7 Q# O) { add_header Access-Control-Allow-Credentials true always;
- @) g7 A: t- G5 n9 h} Access-Control-Allow-Origin Multiple Origin Domains? 的例子:# based on https://gist.github.com/4165271/; ^9 b# N" u. y' B% J
#5 H1 _+ P1 r0 Y* u. a" G9 X4 _# @1 b
# Slightly tighter CORS config for nginx
* v. Q$ g g) A2 U* ~3 Q, a( @#
/ ` K; H7 U$ A1 |% O# A modification of https://gist.github.com/1064640/ to include a white-list of URLs
; T% `# v# d0 |$ W#
4 A' {( u+ C; E+ f% q) r1 h4 C# Despite the W3C guidance suggesting that a list of origins can be passed as part of) H- t$ Y0 K% e
# Access-Control-Allow-Origin headers, several browsers (well, at least Firefox): {2 ~6 O' s2 o" p3 C
# don't seem to play nicely with this.' J3 |' |) y* I) E
#
# ^0 H" x% l8 h$ Z# R% b( K# To avoid the use of 'Access-Control-Allow-Origin: *', use a simple-ish whitelisting0 U6 i( _: { i. k& Z0 P3 r$ L
# method to control access instead.6 _6 P- K' x1 l
#7 Y o9 H7 }' B
# NB: This relies on the use of the 'Origin' HTTP Header.
# n+ t4 ?: U% H( P9 B( [% K3 C2 a5 P/ {: b6 }* e/ _
location / {( M5 W6 T4 o; u
5 F% x# T& D& T" O1 |8 { if ($http_origin ~* (^https?://([^/]+\.)*(domainone|domaintwo)\.com$)) {# U& d( j: Q# a
set $cors "true";/ y3 U: A5 P- s! e5 j& Y! b- y
}
2 B+ X+ H( N% C7 _. f# l! ?, n9 w
1 k9 K! X5 t9 f+ r& B # Nginx doesn't support nested If statements. This is where things get slightly nasty.
w+ e* K$ f$ K7 ^% w # Determine the HTTP request method used
" Z3 V, U) \2 y! ^3 F if ($request_method = 'OPTIONS') {
! Q! P7 }1 p) x set $cors "${cors}options";
' Q3 }/ ~1 C: Z- {! I4 X }# n4 a# [3 y3 t# P) I8 z( j
if ($request_method = 'GET') {. p. {0 p5 L2 g7 A" i( p
set $cors "${cors}get";* f5 e/ V( P$ O* h
}
( u3 R0 {) |/ O3 P1 C if ($request_method = 'POST') {5 @5 J1 }# R0 }
set $cors "${cors}post";
) ]; h5 P& ~" o/ r& u( t }; v+ s5 @0 x+ W s
% ?9 ~4 O* m7 j' x$ S* h( i
if ($cors = "true") {: d2 ?! U" e! T( b) y7 O4 @0 g3 o. T
# Catch all incase there's a request method we're not dealing with properly9 |" h `8 G3 d$ X: m9 k1 ?
add_header 'Access-Control-Allow-Origin' "$http_origin";7 R0 h8 N; }+ f- m C
}" ?/ T7 D+ A6 h7 B
- q8 f" m5 G% b1 _- F! H if ($cors = "trueget") {
9 u+ M" B& Q7 f9 z, B$ L8 a& f/ o8 B add_header 'Access-Control-Allow-Origin' "$http_origin";
8 `; B8 v1 p$ T d/ Z6 m3 e add_header 'Access-Control-Allow-Credentials' 'true';/ L" _8 f3 J3 m& \( S3 s
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';, M- E' d, k: `
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';& T0 Y& n% K) o1 m
}. L" B: F2 e3 u- ?
$ w4 w' e; J& k if ($cors = "trueoptions") {
9 I( b6 b! U' P4 b% \* x5 S add_header 'Access-Control-Allow-Origin' "$http_origin";& Y" B; ?; w, M) |& i( u
5 @1 q: r! v7 f# j5 _ #3 P' d4 t1 |. O
# Om nom nom cookies9 A/ }# n8 l, r1 s) f7 W* q
#
+ R$ g$ {- V) e4 V0 H( l. N add_header 'Access-Control-Allow-Credentials' 'true';: s3 }; ] |( b& W
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';- |; _4 U- ?; ?1 x8 D$ p
% ]/ V2 B2 E+ s- p1 B
#
0 H. T+ r) Y$ t) }) x( |, P G # Custom headers and headers various browsers *should* be OK with but aren't
! w8 `5 }. a3 d6 O #- q" Y' G" D9 {5 O
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';7 H) B3 G0 l5 H ]$ p. S
& X6 _& P7 m* ~ x
#
2 N" O! U l3 N7 }% d # Tell client that this pre-flight info is valid for 20 days; C Q- ]4 R" A) j! X4 R6 h
#
. D7 F* i5 ~9 {) K, C6 `; A add_header 'Access-Control-Max-Age' 1728000;+ x! F! ^7 a- X/ ]
add_header 'Content-Type' 'text/plain charset=UTF-8';/ H: |6 p: a' j! a+ c! Z% H8 H
add_header 'Content-Length' 0;
1 [ ~4 i4 j: m; E O/ Y return 204;
s$ z( N# Q! Z2 O7 f- j5 r9 n }. Y# J5 K* `7 F: B
- S/ P/ n) a# W& g# L/ {7 [* M if ($cors = "truepost") {2 }6 L) [" S1 B, _0 a0 `2 e
add_header 'Access-Control-Allow-Origin' "$http_origin";
. [& ?3 z9 R* q2 a7 r- }8 f7 g add_header 'Access-Control-Allow-Credentials' 'true';* |. \5 V: F3 E! F8 d+ S: }- q
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
, G* i' f1 f7 D add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';' `( [1 F7 M H' x. M" N) V' q
}7 Z# ?* e* m( c3 t
% T" p2 H2 D L1 J0 V
}
5 K [% }& X8 r$ {; `
7 E( s( R# E# M! h/ D6 X8 M. C6 q |
|