以下是gist.github.com支援reverse proxied APIs的範例:
# K6 N# \& Y9 v0 \6 ?
* E( v0 A$ F* g" r
. f1 d+ h1 U- H/ t/ h1 z# _' z# CORS header support
: y8 P8 ], P7 l$ Q3 ^9 l#
( H% O3 P5 D1 N( [6 N# One way to use this is by placing it into a file called "cors_support"
- F( K7 H6 p2 d- \; D3 `9 Z# under your Nginx configuration directory and placing the following3 s1 X0 y, g |% \2 f* N. A/ Q
# statement inside your **location** block(s):
6 ~$ j) J* [/ f# R#0 t+ |6 S8 Z7 N
# include cors_support;
/ N0 K9 R% q# q8 ]' E$ A8 {# o#. O/ {. M$ g8 C, z3 v2 n( B9 y
# As of Nginx 1.7.5, add_header supports an "always" parameter which3 F6 E( @/ ~ V& W2 M% A0 ]* _: G
# allows CORS to work if the backend returns 4xx or 5xx status code.7 D$ m) Y) m# ~. P1 b
#
9 P/ F2 G+ W4 _- }" K6 _+ R5 @, e# For more information on CORS, please see: http://enable-cors.org/0 N8 e. b M+ F0 o# c1 h' B3 ?
# Forked from this Gist: https://gist.github.com/michiel/10646403 v" B5 H6 m( q! J1 I8 [
#
+ g) x: Y6 F9 g3 a1 }. n5 H+ S- x, J
set $cors '';. \; w9 V, Z' \% ?) K/ V
if ($http_origin ~ '^https?://(localhost|www\.yourdomain\.com|www\.yourotherdomain\.com)$') {, U8 w* r; j% e9 c2 I( G8 a, h$ G
set $cors 'true';
1 W) V2 l6 M) M- R8 [8 l) ]}
3 s4 k1 n8 R7 T/ ~, X; z. v3 s( Z9 g: D( D. r. X) M$ P
if ($cors = 'true') {8 Q! I. t/ D9 a2 o0 m
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
; E3 s m7 o% E) g9 c* F6 {8 S- g# K" i add_header 'Access-Control-Allow-Credentials' 'true' always;
8 J* _9 L2 e/ T$ z5 [3 d add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;4 c+ w) c) p7 ]# g
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;4 T( H5 d6 F9 M$ q. }8 L7 u# v
# required to be able to read Authorization header in frontend
2 e9 Z7 p5 {- c% u) B* t( [ #add_header 'Access-Control-Expose-Headers' 'Authorization' always;6 }: i0 t8 M" u* J' } C
}
+ c( N9 b7 @/ W6 e K5 Q/ M
& g! v# W) D: i$ r% {if ($request_method = 'OPTIONS') {
6 `, p7 P, Q7 }+ h+ h2 Z9 q # Tell client that this pre-flight info is valid for 20 days" q7 r2 ]8 @2 G- b$ I
add_header 'Access-Control-Max-Age' 1728000;) a% X- n+ K8 N
add_header 'Content-Type' 'text/plain charset=UTF-8';7 A" Z, |- p/ I, y9 Z! B
add_header 'Content-Length' 0;* H3 A4 F3 n& G/ j' _
return 204;$ @ d7 C [) L4 w$ S
} https://gist.github.com/Stanback/7145487#file-nginx-conf 的討論範例:
: ]! y/ y! }0 R. ]if ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { return 444;/ s- g. z+ t( ?1 z, q3 f2 P7 P
}
( U9 h/ H5 ~2 f5 mset $origin $http_origin;2 |6 q) D* D7 l/ {
if ($origin !~ '^https?://(subdom1|subdom2)\.yourdom\.zone$') {
; F" A) u1 T3 U/ X" X set $origin 'https://default.yourdom.zone';
6 T' S7 i# ^6 m* {' I$ Z: }/ W}. R% U* T+ K: m0 l, N5 P; y; I1 b( ]
if ($request_method = 'OPTIONS') {
" ?9 c9 f/ |0 l0 E& } add_header 'Access-Control-Allow-Origin' "$origin" always;- q' g1 s4 I% u; H
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;! z$ C6 M: B8 ?, O; l
add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always;
4 v) `: Y; o4 r add_header 'Access-Control-Allow-Credentials' 'true' always;0 {9 [$ g6 Q/ [, _6 {" j
add_header Access-Control-Max-Age 1728000; #20 days
6 L& \# z& B; P0 w add_header Content-Type 'text/plain charset=UTF-8';
% K1 U9 n& } q% ^ add_header Content-Length 0;- B9 |6 l+ X; D5 b
return 204;5 h; D- ?# o9 G( G! R# k
}2 d2 J- O h, @9 f
if ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') {9 B9 t: A4 ^7 z/ C) q* q
add_header Access-Control-Allow-Origin "$origin" always;+ y$ r8 e0 H; C+ X- k% v' p& z
add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;) `& d2 z ?: F5 ^
add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always;
2 m. s: @6 H* E3 D4 \: t9 W add_header Access-Control-Allow-Credentials true always;
) f9 t( h8 @5 w$ M" N} Access-Control-Allow-Origin Multiple Origin Domains? 的例子:# based on https://gist.github.com/4165271/+ _7 b; Q/ ]! Q' g3 z" k) b
#
. S$ J8 T4 x a& g0 x9 y3 {# Slightly tighter CORS config for nginx
. K, ^ J2 y, W7 E3 `$ T) }5 W#6 O; ^( m0 U$ e! ]3 |% ` o
# A modification of https://gist.github.com/1064640/ to include a white-list of URLs+ K/ l+ \. O5 w2 F4 z. r
#
7 b; J$ j1 r* X7 k# Despite the W3C guidance suggesting that a list of origins can be passed as part of: w' C" B: g) [ O- ?5 j
# Access-Control-Allow-Origin headers, several browsers (well, at least Firefox)3 [# A0 ~( W: l8 ~" p3 ?9 \8 R& o4 ]
# don't seem to play nicely with this.; Y; |6 [0 I# l5 N8 w1 h0 |
#9 p; z# t( y1 v7 y3 P% J! j) K ~
# To avoid the use of 'Access-Control-Allow-Origin: *', use a simple-ish whitelisting
( h* D9 n l' }# method to control access instead.% n; h+ f/ B! j0 V" E% I
#
' l3 N7 K# z" b; ~. u9 g7 L. R, k/ l7 @# NB: This relies on the use of the 'Origin' HTTP Header.. U6 J3 \, T3 C' B
X- X$ O$ }. T4 q8 ]1 C- t3 Plocation / {" n* ?- Q5 P8 `2 ?! p( R/ a8 y. `* G
- Q% S, i/ V* U& B if ($http_origin ~* (^https?://([^/]+\.)*(domainone|domaintwo)\.com$)) {, \6 m! M" T8 q# v' _7 W. _9 ]
set $cors "true";
, }( w5 q9 o. v' F* i; J }6 o+ g7 \, a! @
' c! S- ?# l4 E8 w" F5 v, R7 n # Nginx doesn't support nested If statements. This is where things get slightly nasty.( ^3 {" }2 {% v: F# t; A5 s. i' A" F
# Determine the HTTP request method used1 ?1 ^+ k; P* H
if ($request_method = 'OPTIONS') {
' W4 L2 i/ k# A; ^8 _: { set $cors "${cors}options"; {8 m1 K' i. W) E% `
}9 w& x3 J$ p3 s" m: `
if ($request_method = 'GET') {
9 G/ a& T( f* x7 j4 H0 w7 ? }8 I- o0 h set $cors "${cors}get";
: X0 H* ]4 n! P, t1 Z }
( f/ ?7 L; _) O if ($request_method = 'POST') {
) n# l1 T- v! X" m; c set $cors "${cors}post";
& |8 ^- m: }; {0 ~! r g% J }# Y1 G0 _, W/ ?
& w$ C& K2 W: R' b% I" T8 M1 ? if ($cors = "true") {
( V( m; R, P4 V; O8 n4 U- g( h% F$ D # Catch all incase there's a request method we're not dealing with properly2 L' c2 Q1 S! n% G, y0 v
add_header 'Access-Control-Allow-Origin' "$http_origin";+ o. y4 t$ Z5 N
}% w1 n) S& d8 I& k6 p2 j
) ^$ Q9 b& M% Z/ q
if ($cors = "trueget") {+ Q" _, j$ M2 Y" a/ H
add_header 'Access-Control-Allow-Origin' "$http_origin";
0 v8 c+ ^" k- ?# ^7 h add_header 'Access-Control-Allow-Credentials' 'true';8 T6 I& u( {5 l1 B: z/ [
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';/ ~; v& d; c8 e6 U( y; L; u% b
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
$ k5 h* l3 C0 d0 t$ A) z# J" i8 @ }) U7 W/ S1 \/ m1 B7 q
8 j: C( r4 w( f7 W* G7 { if ($cors = "trueoptions") {
0 f3 P+ G5 W/ j/ X; e add_header 'Access-Control-Allow-Origin' "$http_origin";
7 C, w3 m" G p* F2 d% l$ ]3 u% F
$ ~$ a, x8 f5 t' C, l #4 T' e2 z r* S$ d
# Om nom nom cookies+ u7 e: C, W! I3 H" B# J- C0 t
#/ i% k( f: |: r/ ]
add_header 'Access-Control-Allow-Credentials' 'true';
5 |1 |% F# O3 C; A add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
% _/ l- p, w- z3 X% v/ j- n0 _) T1 E( O2 {
#
* m" E8 b( c/ i; B* F/ Z0 H # Custom headers and headers various browsers *should* be OK with but aren't, r, [+ `% ^4 Q# v, ]+ H
#
, G7 K( a3 O d0 ]& }- d add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';; T- z! W, \0 J
' c% H# j6 e. [5 K #, T5 S& p6 K3 l3 |, k# {; M
# Tell client that this pre-flight info is valid for 20 days, ^; K( `, H" F& t% n
#5 p B6 {2 m+ \) n) W9 r
add_header 'Access-Control-Max-Age' 1728000;5 l- O+ d* T q7 J. y5 F
add_header 'Content-Type' 'text/plain charset=UTF-8';0 D6 K S; W w6 `3 k9 t, y
add_header 'Content-Length' 0;
/ a5 G& n0 l( [+ U return 204;; ~ d3 x% z- m% r2 r4 d) k
}
/ K! I9 O& ?% E, o/ i
) K6 |1 i) V! n0 [; g# g0 U if ($cors = "truepost") {
- }/ e2 I% D3 L+ I( N- k7 { add_header 'Access-Control-Allow-Origin' "$http_origin";4 Y& c+ f( f9 F
add_header 'Access-Control-Allow-Credentials' 'true';9 f7 D& U1 `( W
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
# H) `, k6 e% \" L* M2 s add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';. X* p+ ^" r; O+ @
}
+ {1 B! b- q8 V i. a/ q+ _' t5 j- e
} ' B* n- M, R& Z# `" p
# k7 e# f6 m: E5 x$ B: s4 |: q
|
|