JavaScript瀏覽器的跨域問題解決方案
為什么要跨域
同源策略
瀏覽器的同源策略:是瀏覽器的一個安全功能,不同源的網頁腳本在沒有明確授權的情況下,不能讀寫對方的資源,也就是會阻止一個域的javascript腳本和另外一個域的內容進行交互
同源
同源指的是(“協(xié)議+域名+端口”)三者相同
跨域問題
解釋:使用AJAX技術(XML HttpRequest對象),從一個網頁去請求另一個網頁的資源時,違反了瀏覽器的同源策略,限制引起的安全問題。
解決跨域的思路:
- 根源上解決,不使用ajax技術
- 授權跨域資源共享
解決跨域
(列舉三個最常用的CORS、JSONP和代理服務器nginx)
CORS
CORS 是跨域資源分享(Cross-Origin Resource Sharing)的縮寫。它是 W3C 標準,屬于跨源 AJAX 請求的根本解決方法。
- 普通跨域請求只需要服務端設置 Access-Control-Allow-Origin
- 帶cookie的跨域請求前后端都需要設置
【前端設置】根據(jù)xhr.withCredentials字段判斷是否帶有cookie
1.原生ajax寫法
var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容 // 前端設置是否帶cookie xhr.withCredentials = true; xhr.open('post', 'http://www.domain2.com:8080/login', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send('user=admin'); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { alert(xhr.responseText); } };
2.jQuery ajax
$.ajax({ url: 'http://www.test.com:8080/login', type: 'get', data: {}, xhrFields: { withCredentials: true // 前端設置是否帶cookie }, crossDomain: true, // 會讓請求頭中包含跨域的額外信息,但不會含cookie });
3.vue-resource
Vue.http.options.credentials = true
4.axios
axios.defaults.withCredentials = true
5.fetch()方法實現(xiàn)
<script> fetch("http://127.0.0.1:35911", // url地址 {method: "GET"}) // 用服務器允許的方法請求 .then{ resonse => response.json{} } // .then{ data => console.log{data.like} }; </script>
fetch方法的node.js后臺設置
cosnt express = require{'express '}; const cors = require{'cors'}; const app = express{}; app.use( cors ({ origin:"*", // 允許所有源進行訪問 methods:['GET','POST'] // 定義可以訪問的方法 }) ); app.get('/',{request,response} =>{ response.json( {"name:"hello","wrold"} ); }); app.listen(35911);
【服務端設置】
服務器端對于CORS的支持,主要是通過設置Access-Control-Allow-Origin來進行的。如果瀏覽器檢測到相應的設置,就可以允許Ajax進行跨域的訪問。
1.Nodejs后臺
var http = require('http'); var server = http.createServer(); var qs = require('querystring'); server.on('request', function(req, res) { var postData = ''; // 數(shù)據(jù)塊接收中 req.addListener('data', function(chunk) { postData += chunk; }); // 數(shù)據(jù)接收完畢 req.addListener('end', function() { postData = qs.parse(postData); // 跨域后臺設置 res.writeHead(200, { 'Access-Control-Allow-Credentials': 'true', // 后端允許發(fā)送Cookie 'Access-Control-Allow-Origin': 'http://www.domain1.com', // 允許訪問的域(協(xié)議+域名+端口) /* * 此處設置的cookie還是domain2的而非domain1,因為后端也不能跨域寫cookie(nginx反向代理可以實現(xiàn)), * 但只要domain2中寫入一次cookie認證,后面的跨域接口都能從domain2中獲取cookie,從而實現(xiàn)所有的接口都能跨域訪問 */ 'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly' // HttpOnly的作用是讓js無法讀取cookie }); res.write(JSON.stringify(postData)); res.end(); }); }); server.listen('8080'); console.log('Server is running at port 8080...');
2.PHP后臺
<?php header("Access-Control-Allow-Origin:*");
JSONP技術原理
JSONP 是服務器與客戶端跨源通信的常用方法。最大特點就是簡單適用,兼容性好(兼容低版本IE),缺點是只支持get請求,不支持post請求。
核心思想:網頁通過添加一個<script>
元素,向服務器請求 JSON 數(shù)據(jù),服務器收到請求后,將數(shù)據(jù)放在一個指定名字的回調函數(shù)的參數(shù)位置傳回來。
1.原生實現(xiàn)
<script src="http://test.com/data.php?callback=dosomething"></script> // 向服務器test.com發(fā)出請求,該請求的查詢字符串有一個callback參數(shù),用來指定回調函數(shù)的名字 // 處理服務器返回回調函數(shù)的數(shù)據(jù) <script type="text/javascript"> function dosomething(res){ // 處理獲得的數(shù)據(jù) console.log(res.data) } </script>
2.Query ajax
$.ajax({ // 請求域名 url:'http://10.10.0.101:8899/login', // 請求方式 type:'GET', // 數(shù)據(jù)類型選擇 jsonp dataType:'jsonp', // 回調方法名 jsonpCallback:'callback', }); // 回調方法 function callback(response) { console.log(response); }
3.Vue.js
this.$http.jsonp('http://www.domain2.com:8080/login', { params: {}, jsonp: 'handleCallback' }).then((res) => { console.log(res); })
代理服務器nginx
跨域限制是瀏覽器的同源策略導致的,使用 nginx
當做服務器訪問別的服務的 HTTP 接口是不需要執(zhí)行 JS 腳本就不存在同源策略限制的,所以可以利用 Nginx
創(chuàng)建一個代理服務器,這個代理服務器的域名跟瀏覽器要訪問的域名一致,然后通過這個代理服務器修改 cookie 中的域名為要訪問的 HTTP接口的域名,通過反向代理實現(xiàn)跨域。
Nginx 的配置信息:
server {
# 代理服務器的端口
listen 88;
# 代理服務器的域名
server_name http://127.0.0.1;
location / {
# 反向代理服務器的域名+端口
proxy_pass http://127.0.0.2:89;
# 修改cookie里域名
proxy_cookie_domain http://127.0.0.2 http://127.0.0.1;
index index.html index.htm;
# 設置當前代理服務器允許瀏覽器跨域
add_header Access-Control-Allow-Origin http://127.0.0.1;
# 設置當前代理服務器允許瀏覽器發(fā)送 cookie
add_header Access-Control-Allow-Credentials true;
}
}
前端代碼:
var xhr = new XMLHttpRequest(); // 設置瀏覽器允許發(fā)送 cookie xhr.withCredentials = true; // 訪問 nginx 代理服務器 xhr.open('get', 'http://127.0.0.1:88', true); xhr.send();
到此這篇關于JavaScript瀏覽器的跨域問題解決方案的文章就介紹到這了,更多相關JS瀏覽器跨域內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
詳解webpack 打包文件體積過大解決方案(code splitting)
這篇文章主要介紹了webpack 打包文件體積過大解決方案(code splitting),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04才發(fā)現(xiàn)的超鏈接js導致網頁中GIF動畫停止的解決方法
才發(fā)現(xiàn)的超鏈接js導致網頁中GIF動畫停止的解決方法...2007-11-11javascript sudoku 數(shù)獨智力游戲生成代碼
javascript sudoku 數(shù)獨智力游戲生成代碼,喜歡的朋友可以參考下。2010-03-03微信小程序實現(xiàn)動態(tài)列表項的順序加載動畫
這篇文章主要為大家詳細介紹了微信小程序實現(xiàn)動態(tài)列表項的順序加載動畫,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-07-07