tid=101068&以下是gist.github.com支援reverse proxied APIs的範例:
8 n$ S2 L+ s$ q% h0 j p& Y1 I- Y; r3 V9 o+ P/ v& t
9 o8 p9 S* u1 V, l" ?6 ?# CORS header support
8 }8 Y, D9 W+ @6 x4 n#
9 A; w- P+ T8 Y! T# One way to use this is by placing it into a file called "cors_support"
: U0 i/ @7 c2 ~( i# under your Nginx configuration directory and placing the following) P3 e! j" y! m& b2 {
# statement inside your **location** block(s):& x0 v. f2 H. J" a+ l
#
9 E; B1 ~; d7 v/ V9 k0 w4 U# include cors_support;
/ J* k r5 M2 x% y( r( J#
9 \- }3 E1 e3 G) _1 A, T) m# As of Nginx 1.7.5, add_header supports an "always" parameter which
6 L7 \2 u4 \; x; x/ _' M# allows CORS to work if the backend returns 4xx or 5xx status code.
& F/ N7 ~- G& Y4 k#; p+ l' J' C& z9 N
# For more information on CORS, please see: http://enable-cors.org/! O2 |3 G$ i; M* a; ~
# Forked from this Gist: https://gist.github.com/michiel/1064640
- s1 b5 D3 w5 m5 d* F5 e* u#
Y8 |& U2 q4 H, B, P: I9 M4 n! F1 n- i+ E$ z4 w
set $cors '';
' A$ c2 H. ^9 B/ n7 z, q- T8 ^if ($http_origin ~ '^https?://(localhost|www\.yourdomain\.com|www\.yourotherdomain\.com)$') {
`; A) H6 B! o3 E8 t set $cors 'true';
! M; q$ {$ ^& T/ l& `9 H}
X2 f: [# i! J* y5 h$ h: k) t. u- R$ [1 _- ~: H
if ($cors = 'true') {' K3 {# r/ P5 m1 M
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
. y7 E7 @% n( n: } add_header 'Access-Control-Allow-Credentials' 'true' always;
/ P9 a2 w0 y+ N; H) R' ~ add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;) W9 T3 d+ G# b8 j- ]- Q
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;
1 |/ L1 i* T. z8 F # required to be able to read Authorization header in frontend/ P& Q7 k( r3 \
#add_header 'Access-Control-Expose-Headers' 'Authorization' always;
{" K8 t# B. M}
0 V' }0 @/ Y* Z0 d: e
' P3 b- s& R4 tif ($request_method = 'OPTIONS') {
$ Z1 v" O8 X, X # Tell client that this pre-flight info is valid for 20 days
: j& Y+ N: K# A% o add_header 'Access-Control-Max-Age' 1728000;
. Q. v5 O2 z' K9 ^" n( [ add_header 'Content-Type' 'text/plain charset=UTF-8';
5 m( C! c4 ^2 r9 X% n$ `, y6 ]$ ?' D add_header 'Content-Length' 0;
+ D: |, E) d+ p7 R9 u return 204;/ h2 a; s0 L' K) o$ v0 r2 d3 C
} https://gist.github.com/Stanback/7145487#file-nginx-conf 的討論範例:
y* @' H! Q# E2 p+ Lif ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { return 444;- L7 ]4 i0 Q8 @7 H, m- h6 h
}
' {9 c |& f0 F+ Eset $origin $http_origin;5 l3 k% y& N$ r2 [1 \- G
if ($origin !~ '^https?://(subdom1|subdom2)\.yourdom\.zone$') {
+ S7 d, L& r1 B2 ]! z set $origin 'https://default.yourdom.zone';9 b# I( p, [; [, L+ v9 S
}+ w5 Y* X a, [. U: {6 d
if ($request_method = 'OPTIONS') {
2 s5 [5 T% B/ C% `0 Q add_header 'Access-Control-Allow-Origin' "$origin" always;6 @2 B" b& x; q9 c$ Q
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
: ~- Q9 p7 m! [; e add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always;
- y, P N. d0 z$ B& t; @ add_header 'Access-Control-Allow-Credentials' 'true' always;. g- ?. b" n/ @( j+ T
add_header Access-Control-Max-Age 1728000; #20 days " M) k" a# b6 c, J! t" Y* ^
add_header Content-Type 'text/plain charset=UTF-8';
& n- F0 ^# u$ Z4 D1 z add_header Content-Length 0;
1 T/ e+ O* P5 X$ l9 y6 \ return 204;. ?# \& O) ~4 E3 E5 e: S
}
! T! v B* f3 N9 S. Z% x4 P* P oif ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') {
& v& u9 S" E/ }$ |6 V- H; X add_header Access-Control-Allow-Origin "$origin" always;. e1 N8 v& V. R2 e5 y2 p
add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
! x* e! |, A5 o. v/ O1 h add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always; D# Z! A1 D6 G6 G& M! H7 \* W @
add_header Access-Control-Allow-Credentials true always;
5 z% P4 F( P {. v N/ z9 Q} Access-Control-Allow-Origin Multiple Origin Domains? 的例子:# based on https://gist.github.com/4165271/
5 ?) ^2 g; }2 N k! S1 X; `#
/ [' g9 l. q8 z) Z0 U) |# Slightly tighter CORS config for nginx+ t! F4 d# r$ k( I0 C5 ~" R
#
; c6 [" m7 D9 P' i4 {# A modification of https://gist.github.com/1064640/ to include a white-list of URLs# R; ]( a0 l r
#
0 u& M! a4 _4 [1 p# Despite the W3C guidance suggesting that a list of origins can be passed as part of
3 F8 t C7 g3 p8 V- P! f2 }; K# Access-Control-Allow-Origin headers, several browsers (well, at least Firefox)% j. d5 g ], E: c4 z
# don't seem to play nicely with this.) m: D* e0 P2 q7 k; q
#
% P Q4 T' X& E# To avoid the use of 'Access-Control-Allow-Origin: *', use a simple-ish whitelisting
1 o0 S* {# X+ j" A6 G3 A# method to control access instead.
, N0 J H2 a% h2 D; I( q7 \#7 y% g8 A% Y( \) Q$ [ p
# NB: This relies on the use of the 'Origin' HTTP Header.
) q( m( A. ^) V6 S& e2 i- X* \3 O: o- W$ ~
location / {+ p; z. W$ h8 u1 \5 @: Q) U3 h
" l5 {/ B2 U6 E( @/ Z if ($http_origin ~* (^https?://([^/]+\.)*(domainone|domaintwo)\.com$)) {* i" E& h6 L3 K
set $cors "true";7 [3 b4 L# E) a9 B- o" _
}
) j' P% C% p) f$ [& l9 F
4 S( ]' J3 x0 n& y/ s # Nginx doesn't support nested If statements. This is where things get slightly nasty.
! Q5 Z% |$ U/ O( a" `" ? # Determine the HTTP request method used$ _3 N$ |4 i4 o7 d
if ($request_method = 'OPTIONS') {
5 h3 n w1 l; J( Z set $cors "${cors}options";$ w9 W2 C; C+ G) ~% i% r
}* Z' M6 F8 B! \6 `9 W- C4 E
if ($request_method = 'GET') {
+ p! _1 x1 W$ K& m* @9 |1 X! m u set $cors "${cors}get";
+ D, g. n/ y& o. K3 L }
0 G) y( k3 w& t. L9 }4 K. T if ($request_method = 'POST') {5 Q" H3 G$ }9 L& U* r
set $cors "${cors}post";
! k! T$ o# s2 a H3 E8 R }
) F& y- ?% e$ L; x5 K" K! u5 s* T* I+ r, Q* h) J4 P$ e! M1 y1 v
if ($cors = "true") {6 [: t4 [# L9 O( c! a) |9 s
# Catch all incase there's a request method we're not dealing with properly8 X' m7 ]/ b; x* X/ o9 \2 q
add_header 'Access-Control-Allow-Origin' "$http_origin";
! \3 T! Y& x# l- v; t) m }
8 D+ {/ m: x/ C) i4 M- K' B& A8 J% C" ]
if ($cors = "trueget") {* J ^$ K: ^! ?* S! z7 ?& w
add_header 'Access-Control-Allow-Origin' "$http_origin";. A+ l2 ?' R) [% ?
add_header 'Access-Control-Allow-Credentials' 'true';
# V4 @2 l! l! A8 m" r% }; R add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';: r% S9 _5 G: O, n$ I3 y. U
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
# Z6 n) y0 |* r2 i6 Y }2 `5 D$ B+ z; ~- s9 ]
7 N& v" z& ]! h, J
if ($cors = "trueoptions") {# T2 l" j% B4 C* A# Z; @0 j x5 Q
add_header 'Access-Control-Allow-Origin' "$http_origin";
% n+ b2 z& n4 u% ^
) h2 J: a* M4 V6 {, e- C5 R #
$ N5 o8 K, D2 u$ ?5 v4 s # Om nom nom cookies0 V1 `1 n( J! c) F
#; }5 Y" Y$ Q$ k: ?' u
add_header 'Access-Control-Allow-Credentials' 'true';
& ]/ o l2 A" p; @% U7 @/ A5 h( v add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';1 D, N& g: f3 ]
1 e; T/ f& ?& u3 r# e1 @
#
" s$ O* k$ f" p3 q6 a6 | # Custom headers and headers various browsers *should* be OK with but aren't
3 f( \& m' J A! a #+ Z* e/ ]: w. ]( {9 m& r2 w
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';! r9 h& z2 m/ X: t$ e
& g9 I% f* ^$ D! z4 O" R ## s' O' t- N6 w, Y" S
# Tell client that this pre-flight info is valid for 20 days
4 ^, b# ~' p/ B7 P/ R o #6 L; |- ^$ l8 ~1 e" p5 G
add_header 'Access-Control-Max-Age' 1728000;7 _( ]! B# r+ g7 g: N4 U" G
add_header 'Content-Type' 'text/plain charset=UTF-8';1 k$ o" i( }/ Z, Z4 y' F) a
add_header 'Content-Length' 0;) V1 K* \. }2 O7 L% s8 Z
return 204;
- @+ M' \) D! O" k6 n; ]0 ~ }0 r. I) M5 T* r; P: T7 N8 \( a
' b1 v4 j% }5 J
if ($cors = "truepost") {
/ @" G z9 R! c/ P add_header 'Access-Control-Allow-Origin' "$http_origin";
' a) c8 v% @$ h6 o add_header 'Access-Control-Allow-Credentials' 'true';
/ G5 s' r) p+ G. m" w0 n add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
" e7 a( K% L0 T( ^/ s add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';3 Q: {& b# x+ m2 }4 ~
}1 X9 A9 S1 O" ~' w1 U" N
9 S F! _; O5 q4 `" b& _$ ?
} , l5 m9 V. S# y( ~3 f- O
0 m9 `! d+ ]' l% _) G; c6 ~3 C
|