以下是gist.github.com支援reverse proxied APIs的範例:2 `+ q0 J6 P6 F' E
0 U* q5 ]- O7 d. h, e6 Y3 A
1 X2 O8 ^1 N: k+ a: ?% ]2 O
# CORS header support
# Z' R* n- f9 L7 |7 i2 w; M#
' a! {5 x E; ]# One way to use this is by placing it into a file called "cors_support"! r6 ~/ |( ~1 g, g$ o: J
# under your Nginx configuration directory and placing the following2 P8 G) v0 j- f
# statement inside your **location** block(s): B3 t, Q4 y" A4 K2 L
#
0 q. _2 |% g/ f. y1 c6 \# include cors_support;( K7 I* K) N" u
#
* ?- n6 q; s& S# As of Nginx 1.7.5, add_header supports an "always" parameter which
$ y( P! e4 M9 B# allows CORS to work if the backend returns 4xx or 5xx status code. ^$ j- X3 w( X9 _
#3 }2 J6 i4 v4 s0 ?0 q5 B' y, R" v6 \
# For more information on CORS, please see: http://enable-cors.org/! i. u3 M: Z8 C5 R
# Forked from this Gist: https://gist.github.com/michiel/1064640
/ H8 y1 f6 e' D) r6 M6 B#
" z+ |" y2 `2 J: B; ]8 E3 l% v% J# B$ }# B& |" l) X/ ?2 ?
set $cors '';' ~8 S% W+ F" T. F
if ($http_origin ~ '^https?://(localhost|www\.yourdomain\.com|www\.yourotherdomain\.com)$') {
; [. g1 h# ^/ g' S5 c, u* P set $cors 'true';
8 I/ l2 R, w6 e; I}2 O$ u8 R+ L* _% l% C
% ?# F0 N; _% _, X' O Wif ($cors = 'true') {3 s, r9 M) a6 A. K
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
9 @" q1 a; r; T, T9 O7 z add_header 'Access-Control-Allow-Credentials' 'true' always;
, d( J' R: W4 x: U8 m; C: j+ }. i add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;& F6 o0 A& r& V3 {/ J2 C
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;
9 h3 F, [$ m' |$ l8 C' |0 l9 A # required to be able to read Authorization header in frontend3 L$ ?3 Y8 K% Q9 ^. v6 F: R
#add_header 'Access-Control-Expose-Headers' 'Authorization' always;, ?8 N. @8 Y. ~4 s7 n
}
3 Z# I* X. M) H" a1 D
: P* d0 r p( zif ($request_method = 'OPTIONS') {
2 S* Y0 {- @# O# B% @ # Tell client that this pre-flight info is valid for 20 days
2 Y) e4 M. Z7 G0 a add_header 'Access-Control-Max-Age' 1728000;: C0 L) Q6 r2 K7 }" s
add_header 'Content-Type' 'text/plain charset=UTF-8';
1 Q. v/ d; g/ n0 [ add_header 'Content-Length' 0;
/ D6 {7 ?& e! c. I return 204;) g; k2 P) u+ S0 _' p& _
} https://gist.github.com/Stanback/7145487#file-nginx-conf 的討論範例:
5 N& \# z) r' b. T' b& n* uif ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { return 444;9 _6 Q9 h; V6 z: k: g y2 u# S
}0 |0 j/ b( f5 }' A: ?) h
set $origin $http_origin;9 M- e$ W- B! n: a. p ]6 J; ^ w
if ($origin !~ '^https?://(subdom1|subdom2)\.yourdom\.zone$') { |' H' Z- M; Q
set $origin 'https://default.yourdom.zone';
4 M$ e1 g) T5 g8 [ @8 A4 z) _; k}1 G) g, L- i! l: Y! m. M
if ($request_method = 'OPTIONS') {8 z! E4 N. E: ]5 l V' K
add_header 'Access-Control-Allow-Origin' "$origin" always;+ ?( c: ^& A- }; } K+ i& A
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;" F! n# e3 X. g6 r! s5 s: q5 s
add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always;
+ m E' x z' G' m7 } add_header 'Access-Control-Allow-Credentials' 'true' always;
9 I0 ?/ q" c4 J add_header Access-Control-Max-Age 1728000; #20 days * p0 ~% K6 P* s7 ^$ C. o
add_header Content-Type 'text/plain charset=UTF-8';
5 L, l/ x# Q% D add_header Content-Length 0;
5 S. q. W& j" {. W4 B' d2 J* Q return 204;
f J$ g0 C# ^# q}
3 K: B; C6 v( K; W) Fif ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') {' l ?9 v' d5 i; n/ i
add_header Access-Control-Allow-Origin "$origin" always;
) T3 W4 a% {5 d3 Y+ | u2 i add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;8 x# k! E B# I( m/ z. V1 n
add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always;
2 ?! I9 s. ~) U add_header Access-Control-Allow-Credentials true always;
" v: O' \3 O( y9 `9 v7 ]} Access-Control-Allow-Origin Multiple Origin Domains? 的例子:# based on https://gist.github.com/4165271/
- Y2 y' |* h: W& Y* N( y4 N# H#0 B% N* E: ]% W3 d1 y# Y
# Slightly tighter CORS config for nginx
' l# F$ G; B1 W#
2 T6 u" j5 [' R! x# A modification of https://gist.github.com/1064640/ to include a white-list of URLs' N0 f. d/ r, `
#2 w& _4 Y* ] q5 S' X' S
# Despite the W3C guidance suggesting that a list of origins can be passed as part of
. G( Z' e) h; |! E( O* C: C# Access-Control-Allow-Origin headers, several browsers (well, at least Firefox)
1 o- c$ E9 ^* F. @# don't seem to play nicely with this.8 J/ }% e- g" O2 o* |( P8 ?) Q
#4 {; }/ O- Y) p* d3 U6 ?5 i
# To avoid the use of 'Access-Control-Allow-Origin: *', use a simple-ish whitelisting
3 E6 V$ E5 q# s# method to control access instead.& j; y& {4 k4 A- b
#! w7 O1 V0 C: Q$ q& G! u# S; `. w
# NB: This relies on the use of the 'Origin' HTTP Header.
( m' q p# D+ R8 M8 l, n3 w* X: I4 f
7 \9 E5 }) u/ Tlocation / {
1 H3 N) j" I2 m3 h8 X+ K; n6 x6 U C3 R ~& l* c+ M* g
if ($http_origin ~* (^https?://([^/]+\.)*(domainone|domaintwo)\.com$)) {; n6 y5 T- i A# j% u
set $cors "true";
2 A3 a9 F/ a: z9 @ }
( V; a6 E0 k4 s$ H* t
/ T" Z% \" F R# z0 a9 ~ # Nginx doesn't support nested If statements. This is where things get slightly nasty.1 k& H! x$ V! q
# Determine the HTTP request method used+ B- W( J+ l" r# z T0 n+ v
if ($request_method = 'OPTIONS') {
/ S+ D, I* C* M! r; n4 l, W; L set $cors "${cors}options";! K! k$ I7 L1 M0 _& g. R
}, z$ f8 d" X9 f7 {
if ($request_method = 'GET') {/ l5 G! J; Q* L- V' { ^5 |+ J
set $cors "${cors}get";
1 \0 v: m8 F8 M' C! S/ l0 X9 b }
. u1 m# t, @% O* b9 Y' L8 w4 Y if ($request_method = 'POST') {
. d9 q8 E8 [( J3 W8 I6 p' N3 v set $cors "${cors}post";
# C) S- W# n$ H% \5 V) x/ L }
4 ~6 }6 \' ^' ]- ] C
3 V1 v. Y* _! t0 C$ v if ($cors = "true") {
6 t" }: Q& X7 x& q- t- I # Catch all incase there's a request method we're not dealing with properly2 P9 g. }; K9 @* ^. P* t9 @7 p2 e. A
add_header 'Access-Control-Allow-Origin' "$http_origin";5 O: P4 F7 p7 \! n: I
}$ T8 i2 s, z# N4 N- l0 b/ T
# p7 e0 V$ B% J8 w
if ($cors = "trueget") {
( |2 Q7 r1 s. s/ o$ f add_header 'Access-Control-Allow-Origin' "$http_origin";' g1 J$ W4 t- A. v. w, d
add_header 'Access-Control-Allow-Credentials' 'true';
' n: f; w j. {' q7 x* G3 \ add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
9 K6 _8 O2 j/ c+ k add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';$ R8 \9 M# R. n3 Y1 ^5 v
}; ^2 H- a- h7 D, W' \
$ k3 Q4 _9 B1 j) m if ($cors = "trueoptions") {
3 D# v. b; h8 S" @: r' D add_header 'Access-Control-Allow-Origin' "$http_origin";
4 I. L8 q0 m2 n3 m, C0 J2 h1 R7 r7 \- D" O1 s( W2 M8 Y
#
# u& X, [( f' q, `+ Z( M9 Z% y # Om nom nom cookies# H3 m4 r1 C6 F
#6 ?" M# `+ F* i' {( p
add_header 'Access-Control-Allow-Credentials' 'true';
2 o- W8 N9 {1 g, f; B7 x4 E add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
9 n$ ]& W6 _' y6 M8 m% @5 W( P5 x6 l5 G( O3 @( o* ^
#+ z2 n, t5 U* @, ^4 h4 _% z( i9 p+ L0 {
# Custom headers and headers various browsers *should* be OK with but aren't
! v+ F3 b% y2 k9 Z #1 ~! l3 l) G9 v! F6 j. a9 Q9 G
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
0 p) H9 z9 |, N9 A
- H& m1 B. A4 D9 a) A #
" g7 Z! F& x6 k1 ?" { @& b6 p! b7 X # Tell client that this pre-flight info is valid for 20 days5 J0 u1 F6 M6 z4 i* G. E9 H3 y
#
, W: c" v! V- d add_header 'Access-Control-Max-Age' 1728000;2 O' Q# D! J I- c
add_header 'Content-Type' 'text/plain charset=UTF-8';% a. l0 H& \' X" Y
add_header 'Content-Length' 0;
# d$ N- o, E( G3 Z return 204;
" P# q/ N" `! v0 A' t& x6 V }- Z4 t7 B) S' M" _& J
# T2 W u4 B* k+ P5 @/ o if ($cors = "truepost") {
5 m; L4 G9 l T3 e" V add_header 'Access-Control-Allow-Origin' "$http_origin";2 E# c/ t6 e0 N& D
add_header 'Access-Control-Allow-Credentials' 'true';
5 d; n* o1 M' D4 w0 J) F" M" E add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';4 w# E9 R7 c! ]: k
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
- \9 i& q+ `& X: N# B }! F$ ~7 m' ~4 [5 V. B3 }8 n* D' g
0 h9 l0 v! }6 @* w
} 0 M9 f# X+ [+ v4 d/ Z" C: {8 i
6 S. P6 q, G C2 a, C1 D- c" W- t+ C
|
|