以下是gist.github.com支援reverse proxied APIs的範例:
2 W* l6 a! V8 h! S" f( \0 ^4 R
9 u: v7 r9 [% k, K
6 C4 b5 x- P. r6 m0 W+ v% f# CORS header support# \# C6 R) S" \3 d9 @/ l
#
5 V5 Y6 H7 |# m2 F+ S" v5 s, ]# One way to use this is by placing it into a file called "cors_support"6 e, Z, u" k( U
# under your Nginx configuration directory and placing the following
' M" V. j* V/ w$ x8 h1 V L8 s' V/ M# statement inside your **location** block(s):
4 R# ?. ]- D- P% D1 n e#% R& V5 U+ f9 T
# include cors_support;: s5 P- ~7 s: z6 f. n
#" q5 O( e8 T/ ]$ {6 A
# As of Nginx 1.7.5, add_header supports an "always" parameter which
% S) I! e) P' @- z; U$ C# allows CORS to work if the backend returns 4xx or 5xx status code.- i4 d7 {- h% I8 L& c
#
0 K: O( Z' c1 i# O# For more information on CORS, please see: http://enable-cors.org/* a/ Q4 k! z* Y1 p2 s3 E
# Forked from this Gist: https://gist.github.com/michiel/10646403 @4 a7 n# K/ Y
#
; C4 l3 h* G! J9 w0 b; b4 |/ r" u
1 H& F( P/ b- K0 l) Bset $cors '';
& C% x- ~7 b7 J# r/ C! Qif ($http_origin ~ '^https?://(localhost|www\.yourdomain\.com|www\.yourotherdomain\.com)$') {
+ s7 z4 A( A. Q% J* J0 { set $cors 'true';
) d( a; _' U8 V+ A5 m l3 f) N$ S}
0 D, N4 l2 p3 s% z, ?5 A3 ?8 m
9 D% g0 x: \5 N# {1 D5 Z% iif ($cors = 'true') {
# B) V, a/ Z' S! H6 |7 A# r+ L add_header 'Access-Control-Allow-Origin' "$http_origin" always;
- F: [) _9 z" o/ @3 I" y9 f add_header 'Access-Control-Allow-Credentials' 'true' always;" A. e. p7 [1 t) U# D
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
4 N7 z3 i+ U& l3 ^/ b* J: ] 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;" K o) O8 r2 p0 i" F3 z0 s
# required to be able to read Authorization header in frontend
; q* f" ?- _ J. N3 Y2 ? #add_header 'Access-Control-Expose-Headers' 'Authorization' always;
" l3 K4 m* f! A' X) \3 U) p3 y! s}; V. x( f% d! ~2 b! K0 l1 l
) A3 ^ Q, j5 h6 W" N5 @8 L
if ($request_method = 'OPTIONS') {
/ S2 ]6 T6 L" E # Tell client that this pre-flight info is valid for 20 days
. K/ o0 B8 a1 K4 ^5 M9 q/ Y add_header 'Access-Control-Max-Age' 1728000;+ D# h/ O# Q- n+ {
add_header 'Content-Type' 'text/plain charset=UTF-8';
( |7 v, d; _+ d$ g! s add_header 'Content-Length' 0;' g S" {, @3 a; B) Y
return 204;; N! ^/ h* }& g* M1 \1 w
} https://gist.github.com/Stanback/7145487#file-nginx-conf 的討論範例:
+ p7 P2 y4 f4 [/ `$ S$ ^if ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { return 444;& u9 E% S# X" o- t( u7 Y
}7 W$ \( p' V1 ~
set $origin $http_origin;1 _( {+ r% I& w. d3 L3 d
if ($origin !~ '^https?://(subdom1|subdom2)\.yourdom\.zone$') {) [# o, V$ A/ R- t
set $origin 'https://default.yourdom.zone';
( q3 Y7 c* e+ T1 X: x}8 T- ]. e; D+ o* \- @
if ($request_method = 'OPTIONS') {
6 ~7 g3 |6 \; \- @ add_header 'Access-Control-Allow-Origin' "$origin" always;
" ~( n/ T3 a8 k% W) c& b4 J add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;: [' e9 E# W8 ` ^$ ]
add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always; m8 I+ R7 F2 s0 d" c
add_header 'Access-Control-Allow-Credentials' 'true' always;
$ `- d! L9 m: G7 B) t* y/ A' J add_header Access-Control-Max-Age 1728000; #20 days ; X) R. \4 q' \+ o
add_header Content-Type 'text/plain charset=UTF-8';3 B: |/ ^1 Q9 f7 {) Z
add_header Content-Length 0;' i% s$ f9 B6 z; F/ S/ S
return 204;
' Q! A0 P. @+ n. [* z2 v% P}
+ ^# ]# ?4 _% l! X8 C: Bif ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') {# {/ g1 y6 {& I9 r; B
add_header Access-Control-Allow-Origin "$origin" always;+ m) S1 J1 [* ]9 R- \6 V
add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
6 u ]8 p* _& v1 r# E$ T add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always;: W: a3 _/ q! m# h
add_header Access-Control-Allow-Credentials true always;$ l% J |3 C7 S# b' X
} Access-Control-Allow-Origin Multiple Origin Domains? 的例子:# based on https://gist.github.com/4165271/
# }3 w. G7 T& `6 S0 D#3 V/ b9 m N5 F7 @/ H; d
# Slightly tighter CORS config for nginx
8 t% v; E6 v) S' ~4 D#
, W: \2 d% c# C# A modification of https://gist.github.com/1064640/ to include a white-list of URLs
. {- j2 l2 J$ x' X n#3 }% C8 p( c5 u; J% c b) w% w7 x
# Despite the W3C guidance suggesting that a list of origins can be passed as part of, H3 r( q$ W# l' A2 v. e L
# Access-Control-Allow-Origin headers, several browsers (well, at least Firefox)6 A" V8 d% W. R9 i7 W; B' r
# don't seem to play nicely with this.$ H6 h9 {, z) L! q( y
#
0 v- a" N* P" F r3 D) w# To avoid the use of 'Access-Control-Allow-Origin: *', use a simple-ish whitelisting' `$ @- Y- a3 q; ~
# method to control access instead.
% I8 ]- s; f5 K#
" k) T# D) n8 Q8 s9 s# NB: This relies on the use of the 'Origin' HTTP Header.2 b+ C% g7 m0 p4 ]5 ~2 o c
' w) s$ q, B) vlocation / {) o# P% ]! I, E0 H& K
% y2 m" l- D4 y
if ($http_origin ~* (^https?://([^/]+\.)*(domainone|domaintwo)\.com$)) {
/ M1 v4 o; f; w8 J. }/ r set $cors "true";
9 O( D j0 F: W- i# M0 D! p }; v# o8 {% a# J4 N: _- q2 F! L5 {
1 {! V" ]8 _$ P' b L # Nginx doesn't support nested If statements. This is where things get slightly nasty.
6 G/ D( }+ \6 O4 U6 v+ e # Determine the HTTP request method used
: q, s$ Y7 Y% O$ q3 m6 j7 M if ($request_method = 'OPTIONS') {! q1 ]7 m4 u1 B
set $cors "${cors}options";. q$ ~/ ]$ B- j1 T. n C
}
; B6 B9 ~! r0 H6 ^ S% A. L if ($request_method = 'GET') {
7 s# v7 Z- ?; O0 f* |6 C set $cors "${cors}get";+ T! U( n$ v) n
}& i8 T0 C/ H" d+ R2 Q+ ]' \0 e
if ($request_method = 'POST') {/ E: J2 C [7 \' p; b( e0 s
set $cors "${cors}post";' a6 {9 E9 V2 p& _
}
( I, L. y+ @; r% E; s" ~( }; h- L1 `1 J# s4 K: V2 E2 D
if ($cors = "true") {( ?6 x: G' G. s: q& \" m2 H
# Catch all incase there's a request method we're not dealing with properly! Q2 A+ c% t, v4 v; ?/ e
add_header 'Access-Control-Allow-Origin' "$http_origin";8 c7 U. G0 R+ R1 u
}6 G" C2 z% a: ~* l$ H; D' d
& j8 W7 b' d- v) q6 A, R if ($cors = "trueget") {
; Y2 O+ r( i1 y* S. t3 H- k: Z add_header 'Access-Control-Allow-Origin' "$http_origin";5 t- R* u6 m* C6 }9 h" l' a/ L9 O
add_header 'Access-Control-Allow-Credentials' 'true';
r' q4 @9 a: @" b$ z add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';6 L' g% n% c& r8 W% p: V1 d
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';3 G2 D* q5 X7 z. i. G1 Y) L
}9 k0 Z$ l9 S0 i5 S! L
2 T* _* v L( }' E1 }. I2 D; ? if ($cors = "trueoptions") {/ w" t ?2 f1 y/ Z4 K+ [9 v
add_header 'Access-Control-Allow-Origin' "$http_origin";' k+ S: `( V4 s$ `
& C& `+ g5 U! _/ r+ ^2 {* l$ ~) C
#; A6 e+ c/ ^% H& k8 T
# Om nom nom cookies n3 A* h4 i* y0 o4 Z* b
#* r9 K2 m D G. x; B; Q$ b
add_header 'Access-Control-Allow-Credentials' 'true'; o, R; p& y+ F( F' T$ w/ b6 t
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
2 A, w8 x' A& v9 d: K' m
2 a! L1 z* S$ [0 _ I* V+ [2 N2 ?7 o #
) k) V( B) P& `* R, r+ J( e7 G # Custom headers and headers various browsers *should* be OK with but aren't
. G" \) s$ B: @) K. X. j% G #
& l6 w4 s* o4 |8 Y1 Q, k. c( P add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
* A% p" S3 |: V7 X6 `, T
+ x& R) b) Y. ?8 g M4 s. ` #1 x1 z+ _: a8 s3 B# N
# Tell client that this pre-flight info is valid for 20 days; x- f( {( M6 ^4 O e1 {
#7 p9 ?# [3 r* O5 D
add_header 'Access-Control-Max-Age' 1728000;
# p* q% N" W( k add_header 'Content-Type' 'text/plain charset=UTF-8';4 i3 P7 y# u; ^ N
add_header 'Content-Length' 0;& C( X4 J8 R6 _ t1 l
return 204;
# d9 k; t4 w9 C- v8 _: [ }
9 U+ r1 w/ L% z8 ]- e+ {
- p1 S+ x: j F, R4 D& y$ ^: j8 D- p3 t if ($cors = "truepost") {+ t) X7 W4 G$ }8 A4 u: |9 h
add_header 'Access-Control-Allow-Origin' "$http_origin";
" l! |0 q5 R# v$ x8 e- @' j+ A add_header 'Access-Control-Allow-Credentials' 'true';* ~: F2 o j* M# x- g; z0 N8 H
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';6 l- {0 |( _( Y7 _6 T$ T, k
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';: ]! F/ M2 N/ ?, S1 l! I
}
+ c& b0 e- R d$ K
7 Y1 D; r: N G9 R+ o} / \" R5 d# H" p. a7 `
2 B7 N2 [' S$ y) P/ V; a( F |
|