tid=101068&以下是gist.github.com支援reverse proxied APIs的範例:
( O9 s1 d& }" v4 Q
( w, s* K# T+ ?. |/ D$ k7 B9 }) R9 t5 p. Q) a
# CORS header support- P- b Z- e* q" Z/ f
## X; }# u- }& r0 N: F" h
# One way to use this is by placing it into a file called "cors_support"
; o8 r) [* }" Q+ O, Y, M; P# under your Nginx configuration directory and placing the following
+ d) x8 i3 C7 f' ?# S# statement inside your **location** block(s):" C% z$ l* K$ f/ a5 K D
#
. L7 o1 B" `$ X# ~7 l. y# include cors_support;( l; @' S, I* E1 E# U x0 s
#7 \9 b8 O2 b) R7 D
# As of Nginx 1.7.5, add_header supports an "always" parameter which/ Z( ~ u* }9 b
# allows CORS to work if the backend returns 4xx or 5xx status code.
; p* j4 b+ b: V- b. ~# L8 f#
. C5 u9 p7 q! l, S# For more information on CORS, please see: http://enable-cors.org/$ ?1 G$ E4 ~; s+ I m
# Forked from this Gist: https://gist.github.com/michiel/1064640. a! }6 m5 h* ]- y# F
#. N2 i# p. ^, V6 `$ Q, d1 X9 h
4 j/ ~$ M# b2 l( B1 cset $cors '';
; |8 A. Z9 R1 F) l6 Yif ($http_origin ~ '^https?://(localhost|www\.yourdomain\.com|www\.yourotherdomain\.com)$') {( ^3 H. W- F$ j' X
set $cors 'true';6 C. ]: o& f2 b& s# ?9 ?# P4 a
}6 g% W) N( r6 T' ^& x# j
4 G2 Y) f4 N$ M, D T- a" |if ($cors = 'true') {* c1 q; h1 B+ p0 I v4 N( } |
add_header 'Access-Control-Allow-Origin' "$http_origin" always;8 u& ^5 L1 m5 E, T1 Z( A
add_header 'Access-Control-Allow-Credentials' 'true' always;
* b+ x. r- u3 ?- C7 t" m9 K, q add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;- e1 p" x- Q2 @) p
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;2 `0 n* A! m2 g2 u a
# required to be able to read Authorization header in frontend" ?3 N9 @, e, x/ b( K# q4 a; p
#add_header 'Access-Control-Expose-Headers' 'Authorization' always;2 x3 C& T5 m$ c
}
5 i; Q6 d: J- ^4 G& _: b* U4 t% i5 u3 U! e" G3 K" h
if ($request_method = 'OPTIONS') {
) f0 m0 w1 A0 l0 _. G # Tell client that this pre-flight info is valid for 20 days' @* z* S2 R T' h4 ~6 C6 Z* O* m2 J
add_header 'Access-Control-Max-Age' 1728000;% _! s3 F4 `. s0 Z( t
add_header 'Content-Type' 'text/plain charset=UTF-8';! E) d" O0 T; C- {9 \3 i
add_header 'Content-Length' 0;4 G" f9 _1 Q# ~5 q" I6 p2 U$ J
return 204;
_. h& g- k9 O+ k2 p. y} https://gist.github.com/Stanback/7145487#file-nginx-conf 的討論範例:: ]2 z3 F7 O: R, m7 R
if ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { return 444;
6 K* W4 e- I% Z' N. @/ ?}& P9 z6 J$ E i" d2 O# a
set $origin $http_origin;' T2 M! G& F+ p( U1 e T( N0 h: w1 \
if ($origin !~ '^https?://(subdom1|subdom2)\.yourdom\.zone$') {5 N# \ a0 B W' ^: Z
set $origin 'https://default.yourdom.zone';/ I& w; z( R; q5 T
}
9 d( q2 M Z, A# M( Q$ c( d/ k* Zif ($request_method = 'OPTIONS') {% `6 Y [& m& w! D
add_header 'Access-Control-Allow-Origin' "$origin" always;
$ v; o# i, r' g2 P- d4 @5 N: ? add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;- ]/ P: Y" y; D1 a, J3 N& a
add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always;
3 D- w. \. [+ N6 k* f& r add_header 'Access-Control-Allow-Credentials' 'true' always;
. @: F2 O. D8 F/ _8 g add_header Access-Control-Max-Age 1728000; #20 days
/ S2 c9 j/ T: e o! f7 Y8 ? add_header Content-Type 'text/plain charset=UTF-8';
. w+ a% h$ R4 q m# ^8 p6 k add_header Content-Length 0;
: P. m' u) C0 O return 204;8 `1 H! i& T7 i* [
}
0 {% s; `# U) B& w+ j3 Qif ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') {
* u& `4 X4 f/ y. N- U. A/ ? add_header Access-Control-Allow-Origin "$origin" always;% S- ?0 M9 f. @0 G, W9 V+ Z. v
add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
, y6 |' x. J- m7 D. k) Q# G add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always;
1 p- O' b9 x, T9 A3 ~" l, V, { add_header Access-Control-Allow-Credentials true always;5 n" H: J: `9 p+ P
} Access-Control-Allow-Origin Multiple Origin Domains? 的例子:# based on https://gist.github.com/4165271/
) i6 t a( I% @! s' L* ]$ z* T3 B8 X#
* D) y/ a* |& u; G. Z# Slightly tighter CORS config for nginx
- A7 R O5 N: u& {& g3 j9 l4 O: t## A3 Z$ @1 ]& B, q) V6 s7 j
# A modification of https://gist.github.com/1064640/ to include a white-list of URLs5 I K$ s9 }$ w/ P
#
t6 `, N4 |& p# Despite the W3C guidance suggesting that a list of origins can be passed as part of$ r$ I6 X0 F0 [8 I( n2 l1 m; G& B
# Access-Control-Allow-Origin headers, several browsers (well, at least Firefox)
. r8 ^2 t; s+ {( e# don't seem to play nicely with this.
/ O! F. ]7 N' o& L8 M7 a* F* m#
7 Q" i" t: w2 T+ ^( J3 p. |- X9 B# To avoid the use of 'Access-Control-Allow-Origin: *', use a simple-ish whitelisting
8 J* w0 T9 n7 t" e# method to control access instead.: s" O7 v- R9 o" E; O
#+ ]7 E' n' h- g z2 m. y$ }( T X
# NB: This relies on the use of the 'Origin' HTTP Header.
2 Q$ t' \" x n- @ G! v; I$ K( e( p# g2 Z1 o
location / {
. b; K9 F7 ~3 r& F0 N9 C0 E. n* M' b# Z
if ($http_origin ~* (^https?://([^/]+\.)*(domainone|domaintwo)\.com$)) {
% O; ~( a2 _0 c3 w( t, @1 @ set $cors "true";4 z: @+ E8 d0 T! o
}9 ?$ E7 }3 s e, h2 G0 \* t
& j. Z/ m6 P @$ D# t # Nginx doesn't support nested If statements. This is where things get slightly nasty.
! D9 C u( b5 C. K # Determine the HTTP request method used* C; s4 _0 W7 @1 ^) r
if ($request_method = 'OPTIONS') {3 X9 r; ?; w! |5 O. @
set $cors "${cors}options";
, h. l1 w$ e( K. k9 x+ g! j; s }9 `% r$ n9 x+ A. e8 g
if ($request_method = 'GET') {
% r' U" \; k! h" \" f9 E; I8 K, M set $cors "${cors}get";
) _% Y, H4 K6 P' t8 Y: L" E }
! R( ]& n" j+ o4 v1 L if ($request_method = 'POST') {+ C3 H# l: i8 @, Z8 ^
set $cors "${cors}post";) h a- J6 w0 S" F/ y& b! |6 `
}' W& T# X3 s" W# ~
+ D c$ { @4 ? o; h if ($cors = "true") {. F- K( ?% ~: [) K! B7 h q& R
# Catch all incase there's a request method we're not dealing with properly
9 _% Z4 Q0 Z! C. u add_header 'Access-Control-Allow-Origin' "$http_origin";
1 y& s* G' ^0 z+ ] X" M }
9 C% @( _$ S( U% ? r& x5 H8 R- ^6 j) P7 T; m
if ($cors = "trueget") {
/ P8 X* u: p# N! U1 H: f3 g add_header 'Access-Control-Allow-Origin' "$http_origin";
- T4 C0 e x/ _" R1 o5 `" V! T; ?9 @) H add_header 'Access-Control-Allow-Credentials' 'true';
4 q: v( N4 X0 K/ L! F" m' e6 P add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';2 l- T4 G) I# }) o3 t
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';3 [9 i F$ q( u1 V
}
) @' X0 b! P- k- j$ I
7 ~; ]; \$ Y: ~# Q2 q) Y if ($cors = "trueoptions") {0 ?0 U& h& l9 a: [: O( |8 i
add_header 'Access-Control-Allow-Origin' "$http_origin";) J! n5 Z' F5 t$ a! W
2 k2 B; d, g$ K7 O% z7 A #4 s j6 h m, d) N: [
# Om nom nom cookies: c4 l& U) ^: v
#
8 z5 c" S' Z* _" O+ B4 F6 T2 E: } add_header 'Access-Control-Allow-Credentials' 'true';
' Z% t. `' e9 c# c( e+ H; Z add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
" E; Y5 C8 f: d7 t/ _8 ]- z: F* C4 _
#$ h1 O7 n; ` ~. E7 Y! e
# Custom headers and headers various browsers *should* be OK with but aren't
2 m2 Y5 j; s# c* {& r! _# V: c1 M3 S #
4 a f4 u+ L. z1 v add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
2 f- ?6 A1 X( G) n7 e1 C. z8 O/ ^$ @" @
#
X; ^! W, @" Q' J' d # Tell client that this pre-flight info is valid for 20 days
+ A( |9 f- v5 G) n- }0 R #+ X$ N* i3 _6 r8 a, B b4 `8 s
add_header 'Access-Control-Max-Age' 1728000;
2 O+ A/ ~8 _3 r- j9 L add_header 'Content-Type' 'text/plain charset=UTF-8'; W8 o; s# g3 k, M. ?
add_header 'Content-Length' 0;
4 X: _. n7 \2 Y" G0 k return 204;
; E2 V! h$ B+ y! t9 E# V7 P }% G$ }& U1 S5 Z
% C- R5 P' X3 d5 s" [" b( V
if ($cors = "truepost") {1 B, n. L* w) a) x0 `
add_header 'Access-Control-Allow-Origin' "$http_origin";+ n9 A; A6 v* k4 d, `$ I
add_header 'Access-Control-Allow-Credentials' 'true';. T% r- @$ D& a1 D+ U2 v2 }. C
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';) ~( L4 J6 J% K8 [6 Z: X
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
, q# Q% M( i" i# O }
) Q, {& M+ t6 g; O$ M/ q& n$ W( R( z+ [$ }+ [5 u
}
1 y7 X8 H+ i4 _/ }
|. R7 R, k0 U2 L, h |