以下是gist.github.com支援reverse proxied APIs的範例:
q9 Z) ^/ M. I- }; E* |6 F" R/ g7 N
! O7 e- R: C3 O: |
# CORS header support5 U" H, |7 Q( A" N) a
#
; K1 h1 h0 ?) M) V, R: T1 B# One way to use this is by placing it into a file called "cors_support"
% B8 Z# |/ a: h7 g. r8 O1 \# under your Nginx configuration directory and placing the following
. o3 J' K I% L( |2 R1 z7 O( y# statement inside your **location** block(s):
; c9 i; Z7 J9 ] E4 S#
( {' y! b3 c5 N J5 x' [5 E% P. g/ u# include cors_support;3 Y8 l* {! |# i& r$ m. m
#+ s1 G- C+ I* _ P- y# ^) [& c
# As of Nginx 1.7.5, add_header supports an "always" parameter which
- V9 x% D" n2 G: e4 j7 x# allows CORS to work if the backend returns 4xx or 5xx status code.
0 m& B d0 O: A. M. Z5 e' h#& K9 f3 E- C: S" ?4 W# o$ \
# For more information on CORS, please see: http://enable-cors.org/
; n: W& p) [ Y1 |" x" h: _: Q# Forked from this Gist: https://gist.github.com/michiel/1064640% b( {8 c/ P& Y7 z3 n$ \ e0 @
#
8 m2 X) @0 r1 W' y) b- Q) M0 t! r# N
( X/ q7 O( k3 {2 O J1 Mset $cors '';3 v: Z* l8 [; m
if ($http_origin ~ '^https?://(localhost|www\.yourdomain\.com|www\.yourotherdomain\.com)$') {
9 I( q4 w# e" f set $cors 'true';# L4 w7 T7 g) F$ A" R
}, v/ T) q9 s9 P& X# T
+ K2 ]' [' a0 {# r6 r
if ($cors = 'true') {
& y( S1 w+ A1 Q! i, G add_header 'Access-Control-Allow-Origin' "$http_origin" always;0 a& @+ X+ y& x- o$ b5 {: W
add_header 'Access-Control-Allow-Credentials' 'true' always;
! [# k- ~. H C: I- I add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;+ }8 b; h* u+ I' J& x$ r; ]
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;
: @, Q( i2 B6 t R; n6 ^. ?3 ` # required to be able to read Authorization header in frontend0 i* o j3 B% }0 @0 C
#add_header 'Access-Control-Expose-Headers' 'Authorization' always;
9 a2 i6 j' k" `& _: }}; X1 g1 ^4 O6 q" E. \
2 |3 v% _( a; \
if ($request_method = 'OPTIONS') {& `8 Z. K2 I3 Q i+ a
# Tell client that this pre-flight info is valid for 20 days4 C1 `4 W5 V4 {( U. x
add_header 'Access-Control-Max-Age' 1728000;
0 _4 b8 b& i9 S add_header 'Content-Type' 'text/plain charset=UTF-8';
8 e) Z0 M5 y6 M9 o add_header 'Content-Length' 0;$ @& |9 q% T+ @# l/ \0 l1 |
return 204;
, F( V) p, O* I. J( F} https://gist.github.com/Stanback/7145487#file-nginx-conf 的討論範例:, ?* _0 m3 F" [! e$ h
if ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { return 444;0 ?- h2 P) |0 u {2 }. Z
}
2 }; h! w7 R8 Xset $origin $http_origin;
9 p( A8 t* A5 k) q& mif ($origin !~ '^https?://(subdom1|subdom2)\.yourdom\.zone$') {
# F# t [: m9 K% u% {" D set $origin 'https://default.yourdom.zone';# }- W8 v5 K9 T$ ]: D1 o
}
0 W0 P& a W4 v, ]- {+ |if ($request_method = 'OPTIONS') {
7 @, S/ p; J& U+ e add_header 'Access-Control-Allow-Origin' "$origin" always;
" T% q8 m, a/ o% B0 J add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;$ Z% S% m3 P. N; i m/ z& L
add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always;
6 R$ E/ O8 c& R% \8 O add_header 'Access-Control-Allow-Credentials' 'true' always;
7 I7 M8 M% h X! g: ?) s add_header Access-Control-Max-Age 1728000; #20 days ' ~2 R/ S4 G$ A2 [
add_header Content-Type 'text/plain charset=UTF-8';: `% u2 e+ q( B1 ~
add_header Content-Length 0;6 W2 ~9 K1 k _) F/ n
return 204;
9 m" G8 |! ~& R# s}
: \, s7 x; T" y% q1 @$ M$ ~5 ?if ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') {; Q8 k' C R( p3 ~
add_header Access-Control-Allow-Origin "$origin" always;
. T1 K% M. ~5 t f# d* s add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
8 M' U9 p" U) M! A/ ~ L' q2 p add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always;
1 o/ P& n/ X4 G4 q add_header Access-Control-Allow-Credentials true always;; e0 l+ J1 X. _
} Access-Control-Allow-Origin Multiple Origin Domains? 的例子:# based on https://gist.github.com/4165271/
6 @: O+ [" v# u* G' S#
# J* L* x* Z9 t% c8 O# Slightly tighter CORS config for nginx7 H0 x; v5 q) q8 J5 v. S( }
#
3 n* s2 A1 t8 G/ k# A modification of https://gist.github.com/1064640/ to include a white-list of URLs
( v H9 s& h! {: }6 C; b8 E#
9 ~3 h: d9 A( b0 w6 Q3 Q' L# Despite the W3C guidance suggesting that a list of origins can be passed as part of" |* K; t1 K! L0 Z0 a% ]
# Access-Control-Allow-Origin headers, several browsers (well, at least Firefox)
4 M- b$ r) e- |2 g# don't seem to play nicely with this.4 _' G; e* P+ n3 P N7 H/ j: c
#9 J7 U. ^* p4 |+ e/ r$ m; a
# To avoid the use of 'Access-Control-Allow-Origin: *', use a simple-ish whitelisting! W! |- y& L) J7 i7 X2 l- G+ l
# method to control access instead.$ {6 l% c& m7 B
#
8 t! \( h4 ^& z* z' V. x7 B5 s' Q- m# NB: This relies on the use of the 'Origin' HTTP Header.6 f: h0 `+ T. r% x0 }" s, G5 _
8 \2 h5 u/ ~' i: F' a6 K2 wlocation / {" \5 I8 x9 H' z
1 r! C2 Q8 u/ {' d, ]$ G2 e if ($http_origin ~* (^https?://([^/]+\.)*(domainone|domaintwo)\.com$)) {% ^' c/ _5 }2 {$ {
set $cors "true";
) g) b# c8 ~, H+ L$ I6 b# z1 x }
% ?& K6 N' }$ ~+ S0 @0 x( M( U' P$ X5 Q5 d" a0 Q
# Nginx doesn't support nested If statements. This is where things get slightly nasty.
: l9 M6 A# g2 f # Determine the HTTP request method used
6 b/ A, D$ A8 n0 m7 W5 D, @# ` if ($request_method = 'OPTIONS') {
' K9 X; |6 L' j' G set $cors "${cors}options";
1 z5 B; A+ `, Q* i5 F. x2 c }. Q# `" |: {7 i6 v& {' l# ?
if ($request_method = 'GET') {
$ y) O1 }7 O3 _7 }5 ] set $cors "${cors}get";: |5 K& T ^* F) K
}$ U w2 {- t3 K( ^6 ^! d, {4 B& I
if ($request_method = 'POST') {! _) R! I9 ]$ ~" @/ r5 g C. J2 ]9 d9 E
set $cors "${cors}post";) d6 ?/ `! y# o6 c
}
1 k+ e/ [7 m; R: L3 E3 c0 n j( Y0 U7 b) H6 l4 D
if ($cors = "true") {
; N+ H; D1 m; g. n ~; x; y # Catch all incase there's a request method we're not dealing with properly
, t* b6 ?/ Y4 [8 o* X add_header 'Access-Control-Allow-Origin' "$http_origin";
. r* g2 A$ j! Y* d, s+ \6 ^ }
+ F, i1 W2 X: i. h
2 D, K( M G z if ($cors = "trueget") {
9 P7 g$ Q1 x0 Y0 M' r9 F add_header 'Access-Control-Allow-Origin' "$http_origin";- i" W; ~5 x- g; s2 F, g
add_header 'Access-Control-Allow-Credentials' 'true';) n4 T& |/ X: I7 V; J I+ Y0 Q
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
5 w3 I, n, r7 c add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
* k) h' D+ l, o9 F6 ` }
0 f3 }0 Z7 H7 |6 T5 `5 \9 F7 ?/ M
( H0 f! N! `; Y) N9 E if ($cors = "trueoptions") {: \. {+ l4 v1 \ Y
add_header 'Access-Control-Allow-Origin' "$http_origin";
7 G# b" n/ y) n) i) v" {$ g& i; o) l0 K
; `. L6 A: H: `6 E; U: D #
0 X4 P9 m: C# l v& y # Om nom nom cookies9 X* ]4 m0 K: j7 G
#
, T; |8 }" i% w# @ add_header 'Access-Control-Allow-Credentials' 'true';% {6 u4 [% q9 _
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
! b2 a) H% P6 e! i. Z0 m% B. H
) w3 X, \, d6 j8 Z* | #) }# e q$ Y8 s1 ` `
# Custom headers and headers various browsers *should* be OK with but aren't* ]1 a; W: M, E: @1 W8 {
#
% H5 i5 j) {& m5 h add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';+ t7 Q; h- k. k o" G W! y& d \
6 m9 w0 b) t+ b: c
#: D. Z8 O6 s5 b# k( J
# Tell client that this pre-flight info is valid for 20 days
+ Q2 r9 w* }1 H. O4 a #: U5 d$ l+ e- }
add_header 'Access-Control-Max-Age' 1728000;5 \9 C; r) k; L4 Q/ w9 Q$ X
add_header 'Content-Type' 'text/plain charset=UTF-8';
0 G) `$ p s" u+ w W9 D! ^ add_header 'Content-Length' 0;! i$ E3 m4 C* T z
return 204;
: z- p0 @# F6 l7 t& K }
1 H! M. D% r, D- x C7 [
( _ H* a% [+ I1 i! u, R if ($cors = "truepost") {
6 k$ E8 s+ x) D+ ^& v add_header 'Access-Control-Allow-Origin' "$http_origin";
. m/ _- v# {: ]$ y# w1 ^2 h' P1 K: X add_header 'Access-Control-Allow-Credentials' 'true';1 k# M+ s; \9 @$ i8 i5 [' P
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';7 c) s& F1 S' ~' a g& @* @6 B9 O
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
" d) o; S* P9 r3 i5 | }
0 }) b! w R: g" ]/ n& s2 U- f! Y H) S) M1 @
} % u( q9 w; Y, k2 _. f, u
& s% B9 O4 n$ T- l" d2 G |
|