以下是gist.github.com支援reverse proxied APIs的範例:
; D- u, `0 \% k
( z$ n( G6 K& @! B" o. m- v: {; r2 H' L9 x+ A
# CORS header support
/ Y0 j' ^1 e) i#( G2 y* h8 b: _ O0 o8 U( K
# One way to use this is by placing it into a file called "cors_support"
% o9 [3 o8 {0 } G. a) b8 A0 s' K# under your Nginx configuration directory and placing the following5 P& E% w$ R& b4 j
# statement inside your **location** block(s):$ ?! b+ L+ F- M& k+ s6 G
#: L/ R/ P% Z' }% J( J; \. W. F
# include cors_support;
% P& S' n6 I& O: o4 W9 X#
% W7 M+ j! O: t* r1 o$ S# As of Nginx 1.7.5, add_header supports an "always" parameter which
- R" C2 [! E* g7 @/ @/ T V# allows CORS to work if the backend returns 4xx or 5xx status code.7 x8 w( Q5 B7 D, X" l
#
, J0 D8 o0 A- O( o+ E0 x# For more information on CORS, please see: http://enable-cors.org/
& C# U/ v1 J/ ~* G2 {# Forked from this Gist: https://gist.github.com/michiel/1064640
7 u! n+ X# e; F+ i#1 F" \7 N2 J9 Q# y4 R
, @" p4 n5 ^/ U7 M7 q% ~
set $cors '';+ j" `2 g5 |/ \6 D3 A* U
if ($http_origin ~ '^https?://(localhost|www\.yourdomain\.com|www\.yourotherdomain\.com)$') {
; ^. b/ I$ e! F" D8 D set $cors 'true';
5 g N7 X& Q. m}% ^; r' w% k7 v* |+ D
) {. V$ K3 f! Y
if ($cors = 'true') {2 l+ i+ N2 s# [! {
add_header 'Access-Control-Allow-Origin' "$http_origin" always;& w6 N2 J( ]( d
add_header 'Access-Control-Allow-Credentials' 'true' always;$ Z* _7 o5 v% z5 R6 x2 }* c
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
6 }+ K% l1 j s8 \, S$ I 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;
, t1 p2 D+ o# s% t/ v7 R- N # required to be able to read Authorization header in frontend
" u2 j# n! r+ \1 k0 n. ~! W; i #add_header 'Access-Control-Expose-Headers' 'Authorization' always;+ {& y. y- G8 m! I% q
}& X* c8 W! o6 }
# p9 |7 j* ~; m) Y, E
if ($request_method = 'OPTIONS') {3 r% t7 i! g# |& h
# Tell client that this pre-flight info is valid for 20 days
4 |; J/ ^ h$ j0 P+ c add_header 'Access-Control-Max-Age' 1728000;
1 C7 ]1 M( L' Z6 |: ~ add_header 'Content-Type' 'text/plain charset=UTF-8';
" {- d! m. X% r! ~- W& N* j add_header 'Content-Length' 0;& j5 p ^% J4 }. }
return 204;
" i/ c$ m, f) g7 g+ j} https://gist.github.com/Stanback/7145487#file-nginx-conf 的討論範例:) ?" k0 ^4 R+ ~' l
if ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { return 444;% u' |: V& e# r+ V4 g* _
}: w2 s1 w( A6 f2 p
set $origin $http_origin;
4 U; m, V0 n8 }if ($origin !~ '^https?://(subdom1|subdom2)\.yourdom\.zone$') {/ e' _9 C) ~: q
set $origin 'https://default.yourdom.zone';7 J" t8 u( ^! _1 P1 A0 E) W
}, h/ Q4 T4 a5 ^! k
if ($request_method = 'OPTIONS') {
) ?* L7 T8 M; ~- h# t/ n add_header 'Access-Control-Allow-Origin' "$origin" always;
5 k4 Q0 q* a( Z3 |, a9 l add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
5 A6 ^ }$ Q9 n7 J! ?: X add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always;$ N" i8 S) w) ]: M7 i
add_header 'Access-Control-Allow-Credentials' 'true' always;
, s% K- A: \( U8 @3 Y* S, ] add_header Access-Control-Max-Age 1728000; #20 days
% h6 U2 o7 {9 c) L4 P& M5 y add_header Content-Type 'text/plain charset=UTF-8';
% U1 R5 p7 z" y* F1 r add_header Content-Length 0;, h+ u8 p1 p+ E3 t5 i( s
return 204;
/ f4 W$ x& Y$ F( \}( K [5 R; b% C& J5 |6 k( ]( Q% P! [
if ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') {7 u# w$ k* ^% Y1 x$ M
add_header Access-Control-Allow-Origin "$origin" always;
7 ?8 r& a! o5 r) @ add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
7 O/ Z3 D7 b: E add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always;1 y8 c! w/ h4 A9 L. x/ v7 ?3 p7 y
add_header Access-Control-Allow-Credentials true always;
) ^, z O9 E( J1 ]) Q4 e# h} Access-Control-Allow-Origin Multiple Origin Domains? 的例子:# based on https://gist.github.com/4165271/
t/ m( X- v6 h, }* l! \- h* M' E#
+ k1 \+ {. \/ j& d; T, q* n# Slightly tighter CORS config for nginx
7 ]. U/ |6 C, b. {+ P#9 z6 s0 F! \/ i# D. X
# A modification of https://gist.github.com/1064640/ to include a white-list of URLs: ~ S: N" r3 q) }0 t6 N# Z. R
#
2 Y8 p5 \' r: K" M' M! A0 h# Despite the W3C guidance suggesting that a list of origins can be passed as part of+ g, t+ k4 J+ U
# Access-Control-Allow-Origin headers, several browsers (well, at least Firefox)
+ M0 \% A6 [+ W* C3 q# don't seem to play nicely with this.1 Z+ u: f4 ]8 B, q/ @
#
- `2 ~, H+ F# N* d9 b3 g& y6 j5 C# To avoid the use of 'Access-Control-Allow-Origin: *', use a simple-ish whitelisting) J$ J- _6 D7 C& L
# method to control access instead.
# c& V* B# m+ ~2 M$ x" i5 t/ Q#/ h w6 b, N! A* |
# NB: This relies on the use of the 'Origin' HTTP Header.
5 i: X, ~) T% Y9 P
5 F& A: f2 h# G) q! Blocation / {: m1 {( d* A+ z" w! u! s
- G& |/ P% K! b( ?
if ($http_origin ~* (^https?://([^/]+\.)*(domainone|domaintwo)\.com$)) {
' l& |0 m6 i& c% N set $cors "true";
1 ]- S$ L) e Z' W }4 m4 t8 p2 |3 @# V
$ u' Z# Z9 X5 x8 J0 }- V6 j # Nginx doesn't support nested If statements. This is where things get slightly nasty." l+ U8 _2 Q" B u$ }
# Determine the HTTP request method used
; Z% n6 l, e" b6 v( F7 k if ($request_method = 'OPTIONS') {8 N, a6 c, X% ^4 ^
set $cors "${cors}options";
4 W& Z6 H/ h. Y/ N d+ I }
: {5 Y& x1 a8 d% q4 A A( d# Q4 I' a if ($request_method = 'GET') {6 J5 c/ k, U* L0 z3 r0 H
set $cors "${cors}get";% A2 P p) B) o
}1 d5 F8 _5 N7 w0 Y8 e
if ($request_method = 'POST') {
7 ` e3 {0 J" ~0 ~8 q) l, B set $cors "${cors}post";# N. U. h+ ~$ _; c2 M2 Z; J
}. ]! l6 H, k4 n6 V% Z0 \
: C) B4 U4 O. Z
if ($cors = "true") {
, N$ w8 {# U( [* p6 W( n4 o' b # Catch all incase there's a request method we're not dealing with properly5 I- [; u# L1 x- @; x
add_header 'Access-Control-Allow-Origin' "$http_origin";5 q! j$ R1 {$ K% E9 k( w- [" x$ K
}
) z& U* r) O6 I1 a
$ \4 o/ a- ^9 N2 j if ($cors = "trueget") {
9 O. x- w0 b2 l F6 p8 }) ? add_header 'Access-Control-Allow-Origin' "$http_origin";" T# I8 o2 M9 i- [6 P
add_header 'Access-Control-Allow-Credentials' 'true';4 v. C: m3 l `) h- K& y0 o
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';. T" h# R+ A" g+ w
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';: l6 D6 s2 b- P) r9 x! m) B
}
D% v! K4 I% \# ]* r3 C# s4 T5 B
# ]/ E1 G/ i6 j- r; g5 T if ($cors = "trueoptions") { P9 Y2 z" ?. \* r4 V4 S
add_header 'Access-Control-Allow-Origin' "$http_origin";
$ s) v3 N \, M/ a% K0 l
: [3 z; q9 Q: u; _. K #
3 [' B6 _3 `+ h! e2 E # Om nom nom cookies
5 |! j7 v8 @7 h5 M' q #: E4 V- M$ t1 B- ~% |2 Q' O
add_header 'Access-Control-Allow-Credentials' 'true';
* T$ ~% A) X" ?' ^, y add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
5 Q: i3 ~1 ~( d6 p- Q* g" G8 C6 f# u5 ?6 _, w1 _8 J
#; ^' X) f! s2 N3 g& P. g% U
# Custom headers and headers various browsers *should* be OK with but aren't+ D* R7 e& M7 X! i) q. N
#; U7 b) {# z3 o8 U& \
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';0 R* R. G4 A" Z2 H# G+ v) Q
" `+ \) ^ H. O" O) A5 W9 J
#
$ f6 [. _# y- `! ]$ O/ m" W # Tell client that this pre-flight info is valid for 20 days
3 J. a# d2 y& E3 n* A #8 s+ F. }& c# b0 w* _
add_header 'Access-Control-Max-Age' 1728000;
- ~$ b3 g1 k5 ?+ y* O add_header 'Content-Type' 'text/plain charset=UTF-8';( z2 D3 ], o( A+ M5 d) o3 J
add_header 'Content-Length' 0;4 S/ C8 M0 ]4 u2 i' f/ d
return 204;
( Z S( X: V8 a2 N( L, y0 U0 {* y9 p1 a }
# C; u% Y4 R( g
' |( ?3 S. @. o( d; _ if ($cors = "truepost") {
0 q3 |: l( B- @% f3 y7 G7 [ add_header 'Access-Control-Allow-Origin' "$http_origin";8 {5 u5 A8 Z: w- z8 p
add_header 'Access-Control-Allow-Credentials' 'true';
; R- L& D1 p' u+ R. C! a5 {* O add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
8 j) r8 \" h' g/ f& w1 X( _4 g add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
) |$ k H0 c# u3 y( W; { }; C# R/ \0 p& t( x8 P5 m" W
# d$ {4 A; ]% F% S1 C+ x0 M" \}
4 [1 `! {4 v; f& W- M" X, S, F* ?1 K: I9 q5 R( u
|
|