以下是gist.github.com支援reverse proxied APIs的範例:
2 X( C' b: E8 U- e% N: l8 [: w0 X, ]: h% ~. L2 }
; B# O: l. c4 R+ y3 C. D
# CORS header support
8 y! s! A. h, k# H: @# q#
9 W4 ~2 h- Q, x* r6 {1 o# j# One way to use this is by placing it into a file called "cors_support"
( g) V- i& x6 X) H0 E$ z4 a: M% ?# under your Nginx configuration directory and placing the following
* ]+ H$ {! O1 r% l0 z( u' S# statement inside your **location** block(s):' m; p% x& [- ]2 w& y
#! E+ c! A* q G$ l9 Y$ v
# include cors_support;5 P! r$ Q+ h) D
#
" O: f4 u" w1 o# As of Nginx 1.7.5, add_header supports an "always" parameter which6 B5 u: Y R d8 P9 M
# allows CORS to work if the backend returns 4xx or 5xx status code.% @9 b, f; L! I4 s# F
#5 N( g- q' u7 t- x0 t: A. ?
# For more information on CORS, please see: http://enable-cors.org/
: ~& N1 T2 L7 z' L+ M# Forked from this Gist: https://gist.github.com/michiel/1064640
( k' m' N. ^9 H8 |) E#
+ \4 V4 o2 ` c( c2 G. T
( S+ A0 T- D1 ^1 x$ N7 pset $cors '';
4 J- i7 k# @+ uif ($http_origin ~ '^https?://(localhost|www\.yourdomain\.com|www\.yourotherdomain\.com)$') { O+ G4 g$ d, T1 R8 A
set $cors 'true';0 p% i) ]' h) K
}
6 Z1 _/ y2 O _3 k' `) `( x" Y3 F! M O# ^0 X, R
if ($cors = 'true') {
# A+ Y& A: t, b4 R* L add_header 'Access-Control-Allow-Origin' "$http_origin" always;
8 \$ m% ]6 O( [/ {" M, D; X add_header 'Access-Control-Allow-Credentials' 'true' always;
8 N+ K5 A' u7 ~% [7 L add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;: \! p1 Q$ ]* P1 t# z7 d
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;7 |) ~- X5 C* Y3 i- Q
# required to be able to read Authorization header in frontend6 Z4 G+ A. Q9 Y: O5 B. z
#add_header 'Access-Control-Expose-Headers' 'Authorization' always;
2 j! A& n0 O$ x% g: K7 [}1 T# n" \ e t" y; E# i1 F5 v3 F
5 D) P) x1 Y/ N/ v- y. `+ p; m
if ($request_method = 'OPTIONS') {
g2 g) ?8 |5 s5 M; N. ` c7 ? # Tell client that this pre-flight info is valid for 20 days
- ^. L/ B. h! k add_header 'Access-Control-Max-Age' 1728000;) m8 b, W: v3 x. E( H% ?7 _. T
add_header 'Content-Type' 'text/plain charset=UTF-8';5 s, j _* a: ^; e: Q
add_header 'Content-Length' 0;
6 }! ]0 x7 D6 e7 m- T* m return 204;
% E; H; _! o- W7 k Q/ F} https://gist.github.com/Stanback/7145487#file-nginx-conf 的討論範例:
7 {* V% u8 a: K" c$ u! o4 Xif ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { return 444;' u+ } G, L+ J5 E$ i( U
}
4 [, [/ {/ v/ ]2 F. xset $origin $http_origin;. b, g: O3 [! O7 a2 u. s9 Z; I
if ($origin !~ '^https?://(subdom1|subdom2)\.yourdom\.zone$') {9 P7 }- z# l* t0 `. r
set $origin 'https://default.yourdom.zone';
9 \' @5 b3 Q. @8 T5 A}% O6 M+ D9 n9 v7 c) r
if ($request_method = 'OPTIONS') {) n( D4 B4 T% t+ B
add_header 'Access-Control-Allow-Origin' "$origin" always;
: x; F) ?3 T5 O/ Z# \3 M5 R add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;9 e z5 E# _8 U: A J. `
add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept, Authorization' always;
/ V* F/ v' A; o- h3 ~% l5 X2 q add_header 'Access-Control-Allow-Credentials' 'true' always;
& e6 g7 Q' o7 Z add_header Access-Control-Max-Age 1728000; #20 days
' y: h& |. K: m; z add_header Content-Type 'text/plain charset=UTF-8';) f& P4 Z& L$ ~3 A, H
add_header Content-Length 0;8 m3 Z: H6 d+ D! d, X( X
return 204;. ^3 K1 O# N9 S7 Y# e
}
4 b% h- P) C7 V8 j ~; S4 {0 `' f7 Fif ($request_method ~ '(GET|POST|PATCH|PUT|DELETE)') {$ m' D c4 V$ d3 _# z& ?3 p, \
add_header Access-Control-Allow-Origin "$origin" always;" @: O: G0 V1 T8 Z) e
add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS' always;
; N) p5 ?9 o3 j# j z# P add_header Access-Control-Allow-Headers 'Content-Type, Accept, Authorization' always;' e6 m8 ^! m1 I, q6 d$ C
add_header Access-Control-Allow-Credentials true always;
/ ?5 Y$ Q" T+ X} Access-Control-Allow-Origin Multiple Origin Domains? 的例子:# based on https://gist.github.com/4165271/# B Q/ O. l M8 O' N9 e* J/ S0 e
#7 w7 N& k& m" Y* e
# Slightly tighter CORS config for nginx3 E* R: k5 z6 b* S/ V8 O0 n7 H- y
#, D5 z$ o3 w* s6 b3 P6 {& h" P( k8 b
# A modification of https://gist.github.com/1064640/ to include a white-list of URLs
4 | z3 `5 `: B4 m#
7 c2 A1 ]" v8 L/ g( z3 Q9 z# Despite the W3C guidance suggesting that a list of origins can be passed as part of
; u2 V9 P3 Q% d! v& S# Access-Control-Allow-Origin headers, several browsers (well, at least Firefox)
0 y4 q% L* r g' Y! ^" R# don't seem to play nicely with this.
$ i( l& D( M5 l, R# X#
: c1 q# x- C6 O1 u# To avoid the use of 'Access-Control-Allow-Origin: *', use a simple-ish whitelisting
: b" G; X0 b% _ K# method to control access instead.
' l1 `( l7 z8 h# C#( Y `/ d6 V9 `8 o; g
# NB: This relies on the use of the 'Origin' HTTP Header.
7 |- `3 X2 Q* j+ B- ~) P
. q9 ?8 x% B. K/ u# a% Qlocation / {- @' X- G# x% m; x2 e
8 V! T2 e W$ R if ($http_origin ~* (^https?://([^/]+\.)*(domainone|domaintwo)\.com$)) {2 N$ J5 l) [7 c
set $cors "true";7 {; }5 } k1 [: c4 b
}
! t* c6 F: p( R' _6 O4 Q
1 r: B7 ?( x: x8 r R6 B # Nginx doesn't support nested If statements. This is where things get slightly nasty.: ]' N0 C5 C' ?3 ?$ a" u
# Determine the HTTP request method used2 a( e, ]" f* S, B
if ($request_method = 'OPTIONS') {
i4 V$ n$ l E/ ?- K9 X7 M set $cors "${cors}options";
' ]7 \3 q# W7 z' q- i* J4 P }! ?$ S2 r* Z. y/ l( _7 R
if ($request_method = 'GET') {" O* Q$ }5 F5 n. Y
set $cors "${cors}get";
1 b" ?' \1 S4 l' S }
* n8 c; P7 u- z" S0 V$ ^7 d) ] if ($request_method = 'POST') {) H: G* N1 u! X5 ~9 z
set $cors "${cors}post"; \. ^! p" A- Z/ j" p0 @5 J% j
}; U0 O7 B( z2 L( K" R* D
2 X3 a0 k, A5 W- P0 D if ($cors = "true") {
$ {* x2 P6 G H& [# A1 X# L # Catch all incase there's a request method we're not dealing with properly
( p2 \9 v" ~; T add_header 'Access-Control-Allow-Origin' "$http_origin";: G6 D* e/ F! w. Q7 q1 M
}' H% [9 a+ |$ s6 s8 c
9 m& h2 F% I$ L8 P if ($cors = "trueget") {: S% c; `8 H. A9 P& ^5 ^" q
add_header 'Access-Control-Allow-Origin' "$http_origin";6 d$ {; G" ?. G' U. i
add_header 'Access-Control-Allow-Credentials' 'true';: o8 O4 |# F3 S2 A
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
# K7 j$ S0 k3 _3 A add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';* c s+ \ ~3 s d$ |
}& Y$ `0 R7 q5 n, ?7 s8 k
( c3 k. d8 \* e' M( f" V/ L* \1 u
if ($cors = "trueoptions") {, T# s. G8 U& K
add_header 'Access-Control-Allow-Origin' "$http_origin";1 J7 u' W8 e2 D/ A3 N u. a
+ d, { T7 l( n: D/ Q8 D; Y# P #4 y9 w! G3 u% H+ ]; G( |3 X
# Om nom nom cookies( T- F! E8 Z }& G) {9 m+ }
#* |! K: q; Y) n, c! D+ a+ K
add_header 'Access-Control-Allow-Credentials' 'true';' @. f9 x8 \1 Z5 y' s. P k
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';7 x3 z# f/ R9 M5 _. Z% a( w
( B. B# E) H5 ]& x #
! K) b( a+ T, v5 K2 n+ x) f% Z # Custom headers and headers various browsers *should* be OK with but aren't, u9 ~' y% U9 s; s
#
5 G. B5 I3 y/ x0 N$ w% m3 Y add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';; d) [0 d" U( M4 b2 I1 r; h) T% M
$ E. i( J6 Y6 c$ h! z! d) @ y( A #
% Z4 d" i. W& l s9 | # Tell client that this pre-flight info is valid for 20 days
' p2 p$ D& B0 _5 ]! H; `% s, Y4 U2 } #9 r: Q3 I+ R1 V) K; o4 h
add_header 'Access-Control-Max-Age' 1728000;7 e+ @* C6 G( ^. L# j7 u. W
add_header 'Content-Type' 'text/plain charset=UTF-8';8 [$ i+ A- J+ i- y
add_header 'Content-Length' 0;
3 x J5 Y" z; ^, o( E( D return 204;
" l+ Q, L! I4 N* W. |1 l. @! w, Q }. T$ K( l& Y2 @; p$ e# e) v
" z8 z6 v; V' ?$ i, n7 q
if ($cors = "truepost") {+ n n6 q0 p0 g# A3 A
add_header 'Access-Control-Allow-Origin' "$http_origin";! b- G4 \$ X9 C6 _2 u- j
add_header 'Access-Control-Allow-Credentials' 'true';. [, ^, |: ]3 Q j C1 [
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
5 k$ M8 [5 o5 L4 J$ R add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
1 U* Q1 v8 [1 B, E3 Y) w8 _1 @ }
. I+ K2 c' q5 Z3 u; u6 z) u3 m- ^. A+ m0 L7 i
}
N, a- W* P2 g$ U6 I
- k# ^$ f9 d) a5 _, B. s$ F |
|