日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
前端跨域請求原理及實踐

一、 跨域請求的含義

做網(wǎng)站、成都做網(wǎng)站過程中,需要針對客戶的行業(yè)特點、產(chǎn)品特性、目標受眾和市場情況進行定位分析,以確定網(wǎng)站的風(fēng)格、色彩、版式、交互等方面的設(shè)計方向。創(chuàng)新互聯(lián)還需要根據(jù)客戶的需求進行功能模塊的開發(fā)和設(shè)計,包括內(nèi)容管理、前臺展示、用戶權(quán)限管理、數(shù)據(jù)統(tǒng)計和安全保護等功能。

瀏覽器的同源策略,出于防范跨站腳本的攻擊,禁止客戶端腳本(如 JavaScript)對不同域的服務(wù)進行跨站調(diào)用。

一般的,只要網(wǎng)站的 協(xié)議名protocol、 主機host、 端口號port 這三個中的任意一個不同,網(wǎng)站間的數(shù)據(jù)請求與傳輸便構(gòu)成了跨域調(diào)用。這也是我們下面實踐的理論基礎(chǔ)。我們利用 NodeJs 創(chuàng)建了兩個服務(wù)器,分別監(jiān)聽 3000、 3001 端口(下面簡稱 服務(wù)器3000 與 服務(wù)器3001 ),由于端口號不一樣,這兩個服務(wù)器以及服務(wù)器上頁面通信構(gòu)成了跨域請求。

在服務(wù)器3000 上有如下的頁面:

服務(wù)器3000 上的請求頁面中包含如下 JavaScript 代碼:

 
 
 
 
  1. $(function() {
  2.     $("#submit").click(function() {
  3.         var data = {
  4.             name: $("#name").val(),
  5.             id: $("#id").val()
  6.         };
  7.         $.ajax({
  8.             type: 'POST',
  9.             data: data,
  10.             url: 'http://localhost:3000/ajax/deal',
  11.             dataType: 'json',
  12.             cache: false,
  13.             timeout: 5000,
  14.             success: function(data) {
  15.                 console.log(data)
  16.             },
  17.             error: function(jqXHR, textStatus, errorThrown) {
  18.                 console.log('error ' + textStatus + ' ' + errorThrown);
  19.             }
  20.         });
  21.     });
  22. }); 

服務(wù)器3000 對應(yīng)的處理函數(shù)為

 
 
 
 
  1. pp.post('/ajax/deal', function(req, res) {
  2.     console.log("server accept: ", req.body.name, req.body.id)
  3.     var data = {
  4.         name: req.body.name + ' - server 3000 process',
  5.         id: req.body.id + ' - server 3000 process'
  6.     }
  7.     res.send(data)
  8.     res.end()
  9. }) 

請求頁面返回結(jié)果:

此處數(shù)據(jù)處理成功。

由于數(shù)據(jù)請求一般都是由頁面發(fā)送數(shù)據(jù)字段,服務(wù)器根據(jù)這些字段作相應(yīng)的處理,如數(shù)據(jù)庫查詢,字符串操作等等。所以我們這里簡單的處理數(shù)據(jù)(在數(shù)據(jù)后面加上字符串‘server 3000 process’),并且返回給瀏覽器,表示數(shù)據(jù)經(jīng)過服務(wù)器端處理。

如果讓 服務(wù)器3000 上的頁面向 服務(wù)器 3001 發(fā)起請求會怎樣呢?

將請求頁面中的 ajax 請求路徑改為:

 
 
 
 
  1. $.ajax({
  2.     ...
  3.     url: 'http://localhost:3001/ajax/deal',
  4.     ...
  5. }); 

服務(wù)器3001 對應(yīng)的處理函數(shù)與 服務(wù)器3000 類似:

 
 
 
 
  1. app.post('/ajax/deal', function(req, res) {
  2.     console.log("server accept: ", req.body.name, req.body.id)
  3.     var data = {
  4.         name: req.body.name + ' - server 3001 process',
  5.         id: req.body.id + ' - server 3001 process'
  6.     }
  7.     res.send(data)
  8.     res.end()
  9. }) 

結(jié)果如下:

結(jié)果證明了我們上面所說的端口號不同,發(fā)生了跨域請求的調(diào)用。

需要注意的是,服務(wù)器 3001 控制臺有輸出:

 
 
 
 
  1. server accept:  chiaki 3001

這說明跨域請求并非是瀏覽器限制了發(fā)起跨站請求,而是請求可以正常發(fā)起,到達服務(wù)器端,但是服務(wù)器返回的結(jié)果會被瀏覽器攔截。

二、 利用 JSONP 實現(xiàn)跨域調(diào)用

說道跨域調(diào)用,可能大家首先想到的或者聽說過的就是 JSONP 了。

2.1 什么是JSONP

JSONP (JSON with Padding or JSON-P) is a JSON extension used by web developers to overcome the cross-domain restrictions imposed by browsers’ same-origin policy that limits access to resources retrieved from origins other than the one the page was served by. In layman’s terms, one website cannot just simply access the data from another website.

It was developed because handling a browsers’ same origin policy can be difficult, so using JSONP abstracts the difficulties and makes it easier.

JSON stands for “JavaScript Object Notation”, a format by which object fields are represented as key-value pairs which is used to represent data.

JSONP 是 JSON 的一種使用模式,可以解決主流瀏覽器的跨域數(shù)據(jù)訪問問題。其原理是根據(jù) XmlHttpRequest 對象受到同源策略的影響,而

這樣從服務(wù)器返回的代碼就可以直接在這個 script 標簽中運行了。下面我們自己實現(xiàn)一個 JSONP:

服務(wù)器 3000請求頁面的 JavaScript 代碼中,只有回調(diào)函數(shù) jsonpCallback:

 
 
 
 
  1. function jsonpCallback(data) {
  2.     console.log("jsonpCallback: "+data.name)

服務(wù)器 3000請求頁面還包含一個 script 標簽:

 
 
 
 

服務(wù)器 3001上對應(yīng)的處理函數(shù):

 
 
 
 
  1. app.get('/jsonServerResponse', function(req, res) {
  2.     var cb = req.query.jsonp
  3.     console.log(cb)
  4.     var data = 'var data = {' + 'name: $("#name").val() + " - server 3001 jsonp process",' + 'id: $("#id").val() + " - server 3001 jsonp process"' + '};'
  5.     var debug = 'console.log(data);'
  6.     var callback = '$("#submit").click(function() {' + data + cb + '(data);' + debug + '});'
  7.     res.send(callback)
  8.     res.end()
  9. }) 

與上面一樣,我們在所獲取的參數(shù)后面加上 “ – server 3001 jsonp process” 代表服務(wù)器對數(shù)據(jù)的操作。從代碼中我么可以看到,處理函數(shù)除了根據(jù)參數(shù)做相應(yīng)的處理,更多的也是進行字符串的拼接。

最終的結(jié)果為:

2.4 JSONP 總結(jié)

至此,我們了解了 JSONP 的原理以及實現(xiàn)方式,它幫我們實現(xiàn)前端跨域請求,但是在實踐的過程中,我們還是可以發(fā)現(xiàn)它的不足:

只能使用 GET 方法發(fā)起請求,這是由于 script 標簽自身的限制決定的。

不能很好的發(fā)現(xiàn)錯誤,并進行處理。與 Ajax 對比,由于不是通過 XmlHttpRequest 進行傳輸,所以不能注冊 success、 error 等事件監(jiān)聽函數(shù)。

三、 使用 CORS 實現(xiàn)跨域調(diào)用

3.1 什么是 CORS?

Cross-Origin Resource Sharing(CORS)跨域資源共享是一份瀏覽器技術(shù)的規(guī)范,提供了 Web 服務(wù)從不同域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,是 JSONP 模式的現(xiàn)代版。與 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。用 CORS 可以讓網(wǎng)頁設(shè)計師用一般的 XMLHttpRequest,這種方式的錯誤處理比 JSONP 要來的好。另一方面,JSONP 可以在不支持 CORS 的老舊瀏覽器上運作?,F(xiàn)代的瀏覽器都支持 CORS。

3.2 CORS 的實現(xiàn)

還是以 服務(wù)器 3000 上的請求頁面向 服務(wù)器 3001 發(fā)送請求為例。

服務(wù)器 3000 上的請求頁面 JavaScript 不變,如下:

 
 
 
 
  1. $(function() {
  2.     $("#submit").click(function() {
  3.         var data = {
  4.             name: $("#name").val(),
  5.             id: $("#id").val()
  6.         };
  7.         $.ajax({
  8.             type: 'POST',
  9.             data: data,
  10.             url: 'http://localhost:3001/cors',
  11.             dataType: 'json',
  12.             cache: false,
  13.             timeout: 5000,
  14.             success: function(data) {
  15.                 console.log(data)
  16.             },
  17.             error: function(jqXHR, textStatus, errorThrown) {
  18.                 console.log('error ' + textStatus + ' ' + errorThrown);
  19.             }
  20.         });
  21.     });
  22. }); 

服務(wù)器 3001上對應(yīng)的處理函數(shù):

 
 
 
 
  1. app.post('/cors', function(req, res) {
  2.     res.header("Access-Control-Allow-Origin", "*");
  3.     res.header("Access-Control-Allow-Headers", "X-Requested-With");
  4.     res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
  5.     res.header("X-Powered-By", ' 3.2.1')
  6.     res.header("Content-Type", "application/json;charset=utf-8");
  7.     var data = {
  8.         name: req.body.name + ' - server 3001 cors process',
  9.         id: req.body.id + ' - server 3001 cors process'
  10.     }
  11.     console.log(data)
  12.     res.send(data)
  13.     res.end()
  14. }) 

在服務(wù)器中對返回信息的請求頭進行了設(shè)置。

最終的結(jié)果為:

3.3 CORS 中屬性的分析

  • Access-Control-Allow-Origin

The origin parameter specifies a URI that may access the resource. The browser must enforce this. For requests without credentials, the server may specify “*” as a wildcard, thereby allowing any origin to access the resource.

  • Access-Control-Allow-Methods

Specifies the method or methods allowed when accessing the resource. This is used in response to a preflight request. The conditions under which a request is preflighted are discussed above.

  • Access-Control-Allow-Headers

Used in response to a preflight request to indicate which HTTP headers can be used when making the actual request.

3.4 CORS 與 JSONP 的對比

CORS 除了 GET 方法外,也支持其它的 HTTP 請求方法如 POST、 PUT 等。

CORS 可以使用 XmlHttpRequest 進行傳輸,所以它的錯誤處理方式比 JSONP 好。

JSONP 可以在不支持 CORS 的老舊瀏覽器上運作。

四、 一些其它的跨域調(diào)用方式

4.1 window.name

window對象有個name屬性,該屬性有個特征:即在一個窗口 (window) 的生命周期內(nèi),窗口載入的所有的頁面都是共享一個 window.name 的,每個頁面對 window.name 都有讀寫的權(quán)限,window.name 是持久存在一個窗口載入過的所有頁面中的,并不會因新頁面的載入而進行重置。

4.2 window.postMessage()

這個方法是 HTML5 的一個新特性,可以用來向其他所有的 window 對象發(fā)送消息。需要注意的是我們必須要保證所有的腳本執(zhí)行完才發(fā)送 MessageEvent,如果在函數(shù)執(zhí)行的過程中調(diào)用了他,就會讓后面的函數(shù)超時無法執(zhí)行。

參考:https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage


本文標題:前端跨域請求原理及實踐
地址分享:http://www.dlmjj.cn/article/djepjgs.html