概述
在瀏覽器端進(jìn)行 Ajax 請(qǐng)求時(shí)會(huì)出現(xiàn)跨域問題,那么什么是跨域,如何解決跨域呢?先看瀏覽器端出現(xiàn)跨域問題的現(xiàn)象,如下圖所示

什么是跨域問題?
跨域,指的是瀏覽器不能執(zhí)行其他網(wǎng)站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對(duì) JavaScript 施加的安全限制。
什么是同源?
所謂同源是指,域名,協(xié)議,端口均相同
http://www.funtl.com-->http://admin.funtl.com跨域
http://www.funtl.com-->http://www.funtl.com非跨域
http://www.funtl.com-->http://www.funtl.com:8080跨域
http://www.funtl.com-->https://www.funtl.com跨域
如何解決跨域問題?
使用 CORS(跨資源共享)解決跨域問題
CORS 是一個(gè) W3C 標(biāo)準(zhǔn),全稱是"跨域資源共享"(Cross-origin resource sharing)。它允許瀏覽器向跨源服務(wù)器,發(fā)出 XMLHttpRequest 請(qǐng)求,從而克服了 AJAX 只能同源使用的限制。
CORS 需要瀏覽器和服務(wù)器同時(shí)支持。目前,所有瀏覽器都支持該功能,IE 瀏覽器不能低于 IE10。整個(gè) CORS 通信過程,都是瀏覽器自動(dòng)完成,不需要用戶參與。對(duì)于開發(fā)者來說,CORS 通信與同源的 AJAX 通信沒有差別,代碼完全一樣。瀏覽器一旦發(fā)現(xiàn) AJAX 請(qǐng)求跨源,就會(huì)自動(dòng)添加一些附加的頭信息,有時(shí)還會(huì)多出一次附加的請(qǐng)求,但用戶不會(huì)有感覺。因此,實(shí)現(xiàn) CORS 通信的關(guān)鍵是服務(wù)器。只要服務(wù)器實(shí)現(xiàn)了 CORS 接口,就可以跨源通信(在header中設(shè)置:Access-Control-Allow-Origin)
使用 JSONP 解決跨域問題
JSONP(JSON with Padding)是 JSON 的一種“使用模式”,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問的問題。由于同源策略,一般來說位于server1.example.com的網(wǎng)頁無法與server2.example.com的服務(wù)器溝通,而 HTML 的<script>元素是一個(gè)例外。利用<script>元素的這個(gè)開放策略,網(wǎng)頁可以得到從其他來源動(dòng)態(tài)產(chǎn)生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料并不是 JSON,而是任意的 JavaScript,用 JavaScript 直譯器執(zhí)行而不是用 JSON 解析器解析(需要目標(biāo)服務(wù)器配合一個(gè)callback函數(shù))。
CORS 與 JSONP 的比較
CORS 與 JSONP 的使用目的相同,但是比 JSONP 更強(qiáng)大。
JSONP 只支持 GET 請(qǐng)求,CORS 支持所有類型的 HTTP 請(qǐng)求。JSONP 的優(yōu)勢(shì)在于支持老式瀏覽器,以及可以向不支持 CORS 的網(wǎng)站請(qǐng)求數(shù)據(jù)。
使用 Nginx 反向代理解決跨域問題
以上跨域問題解決方案都需要服務(wù)器支持,當(dāng)服務(wù)器無法設(shè)置header或提供callback時(shí)我們就可以采用 Nginx 反向代理的方式解決跨域問題。
以下為文件上傳的跨域配置方案:
user? nginx;worker_processes1;events{worker_connections1024;}http{includemime.types;default_type? application/octet-stream;sendfile? ? ? ? on;keepalive_timeout65;server{listen80;server_name upload.myshop.com;add_header'Access-Control-Allow-Origin''*';add_header'Access-Control-Allow-Headers''DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';location/{proxy_pass? http://192.168.0.104:8888;if($request_method='OPTIONS'){add_header Access-Control-Allow-Origin*;add_header Access-Control-Allow-HeadersX-Requested-With;add_header Access-Control-Allow-MethodsGET,POST,PUT,DELETE,PATCH,OPTIONS;# 解決假請(qǐng)求問題,如果是簡單請(qǐng)求則沒有這個(gè)問題,但這里是上傳文件,首次請(qǐng)求為 OPTIONS 方式,實(shí)際請(qǐng)求為 POST 方式# Provisional headers are shown.# Request header field Cache-Control is not allowed by Access-Control-Allow-Headers in preflight response.add_header Access-Control-Allow-HeadersDNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range;return200;}}}}