利用Nginx能夠最簡單且高效解決跨域問題。html
跨域是先後端分離開發中很是常見的問題。這個問題網上已經有很是多的答案,但大部分是編程框架裏面添加CORS頭。但不管用什麼Web框架,現已很難離開Nginx
。所以直接在Nginx
中處理跨域問題有得天獨厚的優點,能夠將OPTIONS
請求攔截在API服務以前,節約服務器開銷。nginx
簡單說,跨域分爲簡單跨域
和複雜跨域
。編程
簡單跨域
不會發送OPTIONS
請求。後端
複雜跨域
會發送一個預檢查OPTIONS
請求。跨域
複雜跨域
的條件是:瀏覽器
Content-Type
不是application/x-www-form-urlencoded
, multipart/form-data
, 或text/plain
。Token
。跨域請求瀏覽器會在Headers中添加Origin
,一般狀況下不容許用戶修改其值。bash
server { listen 80; server_name _; charset utf-8; location / { if ($http_origin ~ '^http(s)?://(localhost|www\.你的域名\.com)$') { add_header 'Access-Control-Allow-Origin' "$http_origin" always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With, Token, x-access-token' always; } if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' "$http_origin" always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With, Token, x-access-token' always; # Tell client that this pre-flight info is valid for 20 days add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain charset=utf-8'; add_header 'Content-Length' 0; return 204; } proxy_http_version 1.1; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-NginX-Proxy true; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://127.0.0.1:8080; proxy_redirect off; } }
GET
請求成功返回跨域頭:服務器
➜ ~ curl -I -H "Origin: http://localhost" http://localhost HTTP/1.1 403 Forbidden Server: nginx/1.15.6 Date: Wed, 14 Nov 2018 07:56:01 GMT Content-Type: text/html; charset=utf-8 Content-Length: 153 Connection: keep-alive Access-Control-Allow-Origin: http://localhost Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With, Token, x-access-token
OPTIONS
預檢請求成功返回跨域頭:app
➜ ~ curl -I -H "Origin: http://localhost" -X OPTIONS http://localhost HTTP/1.1 204 No Content Server: nginx/1.15.6 Date: Wed, 14 Nov 2018 08:19:36 GMT Connection: keep-alive Access-Control-Allow-Origin: http://localhost Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With, Token, x-access-token Access-Control-Max-Age: 1728000 Content-Type: text/plain charset=utf-8 Content-Length: 0