在使用Vue搭建的一個後端管理系統中,我使用axios請求本地的Node環境下的接口,可是請求失敗,而後我錯誤信息是:
大概意思就是不能訪問http://localhost:8080
個人Vue項目端口是http://localhost:8081
,Node服務端運行在http://localhost:8080
端口上,也就是說由於請求端口和響應端口不一致,因此請求失敗。
我也在網上查看了一些關於跨域出現的緣由及解決的方法,並記錄下來。html
跨域一句話的理解就是:服務端和請求端的地址不同。
Ajax 的便利性你們都清楚,能夠在不向服務器提交完整的頁面的狀況下,實現局部更新頁面。可是瀏覽器處於對安全方面的考慮,不容許跨域調用其餘頁面的對象。
其實這個也不能怪瀏覽器,假設誰均可以隨隨便便向你發送請求,那樣有很大的安全隱患。
根據瀏覽器的同源策略, 只有當協議,域名,端口相同的時候纔算是同源, 反之則均視爲是一個跨域的請求.
也就是說我剛剛的Vue端口是8081
,服務端端口是8080
,端口不同,由於同源策略的存在 ,全部個人請求會失敗。前端
一個問題,當找到了緣由,這個問題就解決了一半了。
下面就先介紹三種跨全域的方法:node
應該是最多見解決跨域的方法了,
他爲何能解決跨域呢,是由於Web 頁面上調用 js 文件不受瀏覽器同源策略的影響,因此經過 Script 便籤能夠進行跨域的請求:jquery
個人前端是index.html
,後端是server.js
後端邏輯:ios
//server.js const url = require('url'); const http = require('http'); http.createServer((req, res)=>{ const data = { x: 10//返回的數據 }; const callback = url.parse(req.url, true).query.callback; res.writeHead(200); res.end(`${callback}(${JSON.stringify(data)})`); //執行回調函數,返回data }).listen(3000, 'localhost'); console.log('啓動服務,監聽 localhost:3000');
而後使用node server.js
運行
前端:ajax
//index.html <body> <script> function jsonpCallback(data) { console.log('得到 X 數據:' + data.x); } </script> <script src="http://localhost:3000?callback=jsonpCallback"></script> </body>
以後打開index.html;就能夠在控制檯看到返回的數據了:
npm
至此,經過 JSONP 跨域獲取數據已經成功了,jsonp這種方法跨域,他的兼容性很好,能夠在古老的瀏覽器中國使用,由於這種方法是利用了<script>
標籤的特殊性,全部只支持GET請求。json
CORS 是一個 W3C 標準,全稱是"跨域資源共享"(Cross-origin resource sharing)它容許瀏覽器向跨源服務器,發出 XMLHttpRequest 請求,從而克服了 ajax 只能同源使用的限制。axios
CORS 須要瀏覽器和服務器同時支持才能夠生效,對於開發者來講,CORS 通訊與同源的 ajax 通訊沒有差異,代碼徹底同樣。瀏覽器一旦發現 ajax 請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感受。segmentfault
所以,實現 CORS 通訊的關鍵是服務器。只要服務器實現了 CORS 接口,就能夠跨源通訊。
前端:
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> <script> $.ajax({ url:"http://127.0.0.1:3000", success:function(res){ var res = JSON.parse(res); $('body').text(res.data); console.log(res.data); } }); </script>
此次前端啓動須要使用node-server
來啓動,使用npm install node-server
下載,而後當前目錄下使用node-server
就能夠了
後端:
const http = require('http'); http.createServer((req, res)=>{ const data = { 'data': 'Hello world'//返回的數據 }; res.writeHead(200, {'Access-Control-Allow-Origin': 'http://127.0.0.1:8080'}); //設置的頭部信息須要和前端請求的地址一致 res.end(JSON.stringify(data)); //返回data }).listen(3000, '127.0.0.1'); console.log('啓動服務,監聽 127.0.0.1:3000');
使用命令node server.js
啓動;
CORS與JSONP的使用目的相同,可是比JSONP更強大。
JSONP只支持GET請求,CORS支持全部類型的HTTP請求。JSONP的優點在於支持老式瀏覽器,以及能夠向不支持CORS的網站請求數據。
服務器代理,顧名思義,當你須要有跨域的請求操做時發送請求給後端,讓後端幫你代爲請求,而後最後將獲取的結果發送給你。
假設有這樣的一個場景,你的頁面須要獲取 CNode:Node.js專業中文社區 論壇上一些數據,如經過 https://cnodejs.org/api/v1/topics,當時由於不一樣域,因此你能夠將請求後端,讓其對該請求代爲轉發。
後端代碼以下:
const url = require('url'); const http = require('http'); const https = require('https'); http.createServer((req, res)=>{ const path = url.parse(req.url).path.slice(1); //覈對請求路由是否一致 if(path === 'topics'){ https.get('https://cnodejs.org/api/v1/topics', (resp)=>{ //https代發請求 let data=''; resp.on('data', chunk=>{ data+= chunk }); resp.on('end', ()=>{ res.writeHead( 200, {'Content-Type': 'application/json; charset=utf-8'} ); res.end(data); //返回數據 }) }) } }).listen(3000, '127.0.0.1'); console.log('啓動服務,監聽 127.0.0.1:3000');
前端代碼:
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> <script> $.ajax({ url:"https://cnodejs.org/api/v1/topics", success:function(res){ $('body').text(JSON.stringify(res)); console.log(res); } }); </script>
這樣就成功了
經常使用的跨域方式基本就是這三種:
優勢是能夠兼容老瀏覽器,缺點是隻能發送GET請求
優勢簡單方便,支持post請求,缺點是須要後端的配合,不支持老版瀏覽器。。
優勢是前端正常發送ajax請求,缺點是後端會二次請求。
其餘的跨域方式還有:location.hash
、window.name
、postMessage
等方式,有時間也能夠了解一下。
參考資料: