日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
理解跨域及常用解決方案

跨域,相信大家無論是在工作中還是在面試中經(jīng)常遇到這個問題,常常在網(wǎng)上看到別人所整理的一些方法,看似知道是怎么回事,但如果沒有動手實踐過,總覺得自己沒有真正的掌握,在這里,通過自己認真思考整理一些常用的方法。

10年積累的成都網(wǎng)站設計、成都做網(wǎng)站經(jīng)驗,可以快速應對客戶對網(wǎng)站的新想法和需求。提供各種問題對應的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡服務。我雖然不認識你,你也不認識我。但先網(wǎng)站設計制作后付款的網(wǎng)站建設流程,更有交城免費網(wǎng)站建設讓你可以放心的選擇與我們合作。

跨域的產(chǎn)生

不用多講,作為一名前端開發(fā)人員,相信大家都知道跨域是因為瀏覽器的同源策略所導致的。所謂同源是指"協(xié)議+域名+端口"三者相同,即便兩個不同的域名指向同一個ip地址,也非同源。瀏覽器引入同源策略主要是為了防止XSS,CSRF攻擊。

CSRF(Cross-site request forgery),跨站請求偽造,也被稱為:one click attack/session riding,縮寫為:CSRF/XSRF。

在同源策略影響下,域名A向域名B發(fā)送Ajax請求,或操作Cookie、LocalStorage、indexDB等數(shù)據(jù),或操作dom,js就會受到限制,但請求css,js等靜態(tài)資源不受限制

跨域的解決方案

1 通過jsonp跨域

首先說一下jsonp的原理,例如我們平時寫html的時候常常會使用

這種方式去取放在另外服務器上的靜態(tài)資源,這個是不受同源策略所限制的,所以我們利用這一點可以解決跨域的問題。

主要代碼如下:

1.1原生實現(xiàn) 

 
 
 
 
  1. 在www.a.com域名寫下如下代碼,去請求www.b.com域名的數(shù)據(jù)  
  2.  

這里,我們利用動態(tài)腳本的src屬性,變相地發(fā)送了一個http://www.b.com/getdata?call...。這時候,b.com頁面接受到這個請求時,如果沒有JSONP,會正常返回json的數(shù)據(jù)結果,像這樣:{ msg: 'helloworld' },而利用JSONP,服務端會接受這個callback參數(shù),然后用這個參數(shù)值包裝要返回的數(shù)據(jù):demo({msg: 'helloworld'});

這時候,如果a.com的頁面上正好有一個demo 的函數(shù):

 
 
 
 
  1. function demo(res){  
  2. console.log(res);   

當遠程數(shù)據(jù)一返回的時候,隨著動態(tài)腳本的執(zhí)行,這個demo函數(shù)就會被執(zhí)行。

1.2 jquery ajax請求實現(xiàn) 

 
 
 
 
  1. $.ajax({  
  2.     url:'http://www.b.com/getdata',  
  3.     type:'get',  
  4.     dataType: 'jsonp',  // 請求方式為jsonp  
  5.     jsonpCallback: 'demo', // 自定義回調(diào)函數(shù)名  
  6.     data: {}  
  7. }); 

服務端代碼實現(xiàn):

以nodejs為例 

 
 
 
 
  1. var http = require(http);  
  2. //引入url模塊解析url字符串  
  3. var url = require('url);  
  4. //引入querystring模塊處理query字符串  
  5. var querystring = require('querystring');  
  6. var server = http.createServer();  
  7. server.on('request',function(req,res){  
  8.     var urlurlPath = url.parse(req.url).pathname;  
  9.     var param = querystring .parse(req.url.split('?')[1]);   
  10.     if(urlPath === '/getData' && param.callback) {    
  11.         res.writeHead(200,{'Content-Type','application/json;charset=utf-8'});   
  12.  
  13.         var data = { msg: 'helloworld' };  
  14.         data = JSON.stringify(data );      
  15.  
  16.         var callback = param .callback+'('+data+');';  
  17.         res.write(callback);      
  18.  
  19.         res.end();  
  20.     } else {  
  21.         res.writeHead(200, {'Content-Type':'text/html;charset=utf-8'});       
  22.  
  23.         res.write('Hell World\n');  
  24.         res.end();     
  25.  
  26.     }  
  27. }) 

jsonp缺點:只能使用get請求,不推薦使用

2 CORS 跨域資源共享

跨域資源共享(CORS) 是一種機制,它使用額外的 HTTP 頭來告訴瀏覽器 讓運行在一個 origin (domain) 上的Web應用被準許訪問來自不同源服務器上的指定的資源。當一個資源從與該資源本身所在的服務器不同的域或端口請求一個資源時,資源會發(fā)起一個跨域 HTTP 請求。

Cross-Origin Resource Sharing跨域資源共享,應該算是現(xiàn)在比較推薦的跨域處理方案.不僅適用于各種Method,而且更加方便和簡單

目前,所有瀏覽器都支持該功能,IE瀏覽器不能低于IE10。

2.1 簡單請求和非簡單請求

瀏覽器將CORS請求分成兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。

簡單請求同時滿足以下條件,只要不滿足以下條件的則為非簡單請求

非簡單請求會發(fā)出一次預檢測請求,返回碼是204,預檢測通過才會真正發(fā)出請求,這才返回200。這里通過前端發(fā)請求的時候增加一個額外的headers來觸發(fā)非簡單請求。

2.2 進行帶有身份憑證的CORS 請求

  •  默認情況下的跨域請求都是不會把cookie發(fā)送給服務器的,在需要發(fā)送的情況下,如果是xhr,那么需要設置xhr.withCredentials=true,
  •  如果是采用fetch獲取的話,那么需要在request里面設置 credentials:'include',
  •  但是如果服務器在預請求的時候沒返回Access-Control-Allow-Crenditials:true的話,那么在實際請求的時候,cookie是不會被發(fā)送給服務器端的,要特別注意對于簡單的get請求,不會有預請求的過程,
  •  那么在實際請求的時候,如果服務器沒有返回Access-Control-Allow-Crenditials:true的話那么響應結果瀏覽器也不會交給請求者

對于附帶身份憑證的請求,服務器不得設置 Access-Control-Allow-Origin 的值為“*”。

這是因為請求的首部中攜帶了 Cookie 信息,如果 Access-Control-Allow-Origin的值為“*”,請求將會失敗。而將 Access-Control-Allow-Origin 的值設置為http://www.a.com,則請求將成功執(zhí)行。

2.3 HTTP 響應首部字段

  •  Access-Control-Allow-Origin: | *
  •  Access-Control-Expose-Headers 頭讓服務器把允許瀏覽器訪問的頭放入白名單
  •  Access-Control-Max-Age 頭指定了preflight請求的結果能夠被緩存多久
  •  Access-Control-Allow-Credentials

    頭指定了當瀏覽器的credentials設置為true時是否允許瀏覽器讀取response的內(nèi)容。

  •  Access-Control-Allow-Methods 首部字段用于預檢請求的響應。其指明了實際請求所允許使用的 HTTP 方法。
  •  Access-Control-Allow-Headers 首部字段用于預檢請求的響應。其指明了實際請求中允許攜帶的首部字段。

2.4 以nodejs express為例,說明如何使用cors解決跨域 

 
 
 
 
  1. var express=require('express');  
  2. var url=require('url');  
  3. var app=express();  
  4. var allowCrossDomain = function(req, res, next) {  
  5.     res.header('Access-Control-Allow-Origin', 'http://localhost:63342');  
  6.     res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');  
  7.     res.header('Access-Control-Allow-Headers', 'Content-Type');  
  8.     res.header('Access-Control-Allow-Credentials','true');  
  9.     next();  
  10. };  
  11. app.use(allowCrossDomain);  
  12. app.get('/getData',function (req,res,next) {  
  13.     var queryValue=url.parse(req.url).query;  
  14.     if(queryValue==='fortunewheel@sina.com'){  
  15.         res.send(true);  
  16.     }else {  
  17.         res.send(false);  
  18.     }  
  19. });  
  20. app.listen(3001); 

實際開發(fā)過程中,為了安全,會和token一起使用

3 window.postMessage

postMessage是HTML5 XMLHttpRequest Level 2中的API,且是為數(shù)不多可以跨域操作的window屬性之一,它可用于解決以下方面的問題:

  •  iframe嵌套頁面跨域通信
  •  頁面和其打開的新窗口的通信
  •  多窗口之間消息傳遞

用法:

postMessage(data,origin)方法接受兩個參數(shù),

data:需要傳遞的數(shù)據(jù),html5規(guī)范支持任意基本類型或可復制的對象,但部分瀏覽器只支持字符串,所以傳參時最好用JSON.stringify()序列化。

origin:協(xié)議+主機+端口號,也可以設置為"*",表示可以傳遞給任意窗口,如果要指定和當前窗口同源的話設置為"/"。

代碼示例:

http://www.a.com/a.html 

 
 
 
 
  1.   
  2.  

http://www.b.com/b.html 

 
 
 
 
  1.  

4 document.domain

這種方式只適合主域名相同,但子域名不同的iframe跨域。

實現(xiàn)原理:兩個頁面都通過js強制設置document.domain為基礎主域,就實現(xiàn)了同域。

使用方式:

http://www.a.com/a.html 

 
 
 
 
  1.   
  2.  

"http://www.child.a.com/b.html 

 
 
 
 
  1.  

5 window.name

window.name 傳輸技術的基本原理:

當在瀏覽器中打開一個頁面,或者在頁面中添加一個iframe時即會創(chuàng)建一個對應的window對象,當頁面加載另一個新的頁面時,window.name的屬性是不會變的。這樣就可以利用在頁面動態(tài)添加一個iframe然后加載數(shù)據(jù)頁面,在數(shù)據(jù)頁面將需要的數(shù)據(jù)賦值給window.name。然而此時承載的iframe的parent頁面還是不能直接訪問不在同一域下的iframe的那么屬性,這時,只需要將iframe再加載一個與承載頁面同域的空白頁面,即可對window.name進行數(shù)據(jù)讀取。

通過iframe的src屬性由外域轉向本地域,跨域數(shù)據(jù)即由iframe的window.name從外域傳遞到本地域。這個就巧妙地繞過了瀏覽器的跨域訪問限制,但同時它又是安全操作。

具體實現(xiàn):

http://www.a.com/a.html 主頁面

http://www.b.com/b.html 數(shù)據(jù)頁面

http://www.a.com/proxy.html 代理頁面

http://www.a.com/a.html代碼: 

 
 
 
 
  1.  

http://www.b.com/b.html代碼: 

 
 
 
 
  1. window.name = '123' 

http://www.a.com/proxy.html空白

6 nginx代理跨域 

 
 
 
 
  1. server{  
  2.     # 監(jiān)聽8080端口  
  3.     listen 8080;  
  4.     # 域名是localhost  
  5.     server_name localhost;  
  6.     #凡是localhost:8080/api這個樣子的,都轉發(fā)到真正的服務端地址http://www.b.com:8080   
  7.     location ^~ /api {  
  8.         proxy_pass http://www.b.com:8080;  
  9.     }      

配置之后就不需要前端做什么修改了,一般我們在前后端分離項目中開發(fā)階段會采用這種方式,但不是所有場景都能這樣做,例如后端接口是一個公共的API,比如一些公共服務獲取天氣什么的。

7 WebSocket協(xié)議跨域

websoket協(xié)議天然支持跨域,你只需要學會如何使用它即可,關于websocket協(xié)議請看我的另外一篇文章WebSocket網(wǎng)絡通信協(xié)議


新聞名稱:理解跨域及常用解決方案
文章位置:http://www.5511xx.com/article/ccoihsg.html