前端跨域戰略實踐----cors,jsonp

原文地點:
https://github.com/HolyZheng/…

相識幾個跨域的計劃,而且經由過程簡樸實踐舉行體味。

怎樣實踐?

然則,我們怎樣舉行實踐呢?在哪發要求?向什麼效勞器發要求?很簡樸,就在當前網頁,翻開掌握台,輸入要求的代碼

var url = 'http://127.0.0.1:8888/';
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.send();

那末我們就能夠以當前頁面url作為origin,向http://127.0.0.1:8888/ ,發送要求GET要求了。
同時在當地建立一個node效勞

var http = require('http');

http.createServer(function (request, response) {

    response.writeHead(200, {
      'Content-Type': 'text/plain'
    });

    response.end('request success!!!');
}).listen(8888);

console.log('Server running at http://127.0.0.1:8888/');

如許我們就有效勞器了,你能夠很輕鬆的隨着這遍文章來實踐了,然後從當前網頁發送get要求到當地效勞,天經地義跨域了。

ps: github網站不可(本文最初再github上編寫),會激發csp毛病,此毛病是用於防備內容注入進擊的,不得不說,大網站平安措施做得就是好,轉戰segmentfault做實踐。

《前端跨域戰略實踐----cors,jsonp》

1. cors

cors(跨域資源共享 Cross-origin resource sharing),它許可瀏覽器向跨域效勞器發出XMLHttpRequest要求,從而戰勝跨域題目,它須要瀏覽器和效勞器的同時支撐。

cors 分為兩種要求,簡樸要乞降非簡樸要求,關於cors的更細緻引見,引薦阮一峰先生的
跨域資源共享 CORS 詳解,本文注意實踐。

簡樸要求

正如上方的例子就是一個簡樸要求

var url = 'http://127.0.0.1:8888/';
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.send();

怎樣處置懲罰此案例的跨域題目呢?
瀏覽器端,瀏覽器會自動在要求頭中增加 origin 字段,我們不須要操縱。

Request Headers: 
Origin: https://github.com

效勞端,Access-Control-Allow-Origin屬性,我們須要效勞端設置此屬性,指定許可的要求源域名,能夠經由過程指定為 *來指定所以域名。後端動起來:

var http = require('http');

http.createServer(function (request, response) {

    response.writeHead(200, {
      'Content-Type': 'text/plain',
      'Access-Control-Allow-Origin': '*'
    });

    response.end('request success!!!');
}).listen(8888);

console.log('Server running at http://127.0.0.1:8888/');

重啟效勞,再嘗試

《前端跨域戰略實踐----cors,jsonp》
此次沒有再報錯了,我們看看效勞器放回了什麼
《前端跨域戰略實踐----cors,jsonp》
nice!跨域勝利!

非簡樸要求

一樣我們在掌握台輸入一下代碼舉行put(非簡樸要求)

var url = 'http://127.0.0.1:8888/';
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.send();

毫無不測的報錯

《前端跨域戰略實踐----cors,jsonp》

在舉行非簡樸要求的時刻,瀏覽器會先發送一次OPTION要求來“預檢”(preflight)該要求是不是被許可,要求頭中會經由過程Access-Control-Request-MethodAccess-Control-Request-Headers來通知效勞器我須要用到的要領和字段,效勞器經由過程返回的頭部信息中的Access-Control-Allow-OriginAccess-Control-Allow-Method來通知瀏覽器該跨域要求是不是被許可。修正後端代碼:

var http = require('http');

http.createServer(function (request, response) {

    response.writeHead(200, {
      'Content-Type': 'text/plain',
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, PUT'
    });

    response.end('request success!!!');
}).listen(8888);

console.log('Server running at http://127.0.0.1:8888/');

能夠看到瀏覽器會先發送一個預檢

《前端跨域戰略實踐----cors,jsonp》

當確認許可跨域今後,今後再發送該要求,就會省去預檢處置懲罰,之間看成簡樸要求來操縱。很明顯,修正了後端代碼后,此次的put要求時勝利的。這裏就不繼承上圖了。

cors總結

cors(跨域資源共享 Cross-origin resource sharing),它許可瀏覽器向跨域效勞器發出XMLHttpRequest要求,從而戰勝跨域題目,它須要瀏覽器和效勞器的同時支撐。

  1. 瀏覽器端會自意向要求頭增加origin字段,表明當前要求泉源。
  2. 瀏覽器端須要設置相應頭的Access-Control-Allow-MethodsAccess-Control-Allow-HeadersAccess-Control-Allow-Origin等字段,指定許可的要領,頭部,源等信息。
  3. 要求分為簡樸要乞降非簡樸要求,非簡樸要求會先舉行一次OPTION要領舉行預檢,看是不是許可當前跨域要求。

2. jsonp

jsonp的道理就是應用就是應用script標籤沒有跨域限定,能夠經由過程script標籤的src屬性發送GET要求。我們繼承嘗試,先把後端有關跨域的設置去掉,並重啟效勞

var http = require('http');

http.createServer(function (request, response) {

    response.writeHead(200, {
      'Content-Type': 'text/plain'
    });

    response.end('request success!!!');
}).listen(8888);

console.log('Server running at http://127.0.0.1:8888/');

翻開我們的掌握台輸入一下代碼,應用script標籤舉行jsonp要求

var script = document.createElement('script');
script.type = 'text/javascript';
script.src = `http://127.0.0.1:8888/`;
document.head.appendChild(script);

能夠看到,後端一般的返回了

request success !!!

而且該要求為GET要求

Request URL: http://127.0.0.1:8888/
Request Method: GET
Status Code: 200 OK
Remote Address: 127.0.0.1:8888
Referrer Policy: no-referrer-when-downgrade

然則我們如今只是勝利發送了一個跨域要求,然則我們不像XMLHttpRequest那樣能夠在res.responseText中拿到數據,經由過程jsonp我們該怎樣拿到要求的數據呢?要領就是前後端商定一個callback字段名,來通報函數名,前端經由過程該函數來拿到數據。前端代碼修正為:

var script = document.createElement('script');
script.type = 'text/javascript';
script.src = `http://127.0.0.1:8888/?callback=onBack`;
document.head.appendChild(script);
function onBack (res) {
  console.log(JSON.stringify(res));
  // 要求完后刪除增加到頁面上的script標籤
  var head = document.head
  head.removeChild(script)
}

經由過程callback字段來通報函數名onBack,後端代碼修正為

var http = require('http')
var urlTool = require('url')
// json 數據
var data = {'methods': 'jsonp', 'result': 'success'};

http.createServer(function (request, response) {
    var params = urlTool.parse(request.url, true)
    console.log(params)
    response.writeHead(200, {
      'Content-Type': 'text/plain'
    });
    if (params.query && params.query.callback) {

      // callback(data)
      var str = `${params.query.callback}(${JSON.stringify(data)})`
    }

    response.end(str);
}).listen(8888);

console.log('Server running at http://127.0.0.1:8888/');

重啟後端效勞,而且在掌握台輸入代碼,能夠看到效果:

《前端跨域戰略實踐----cors,jsonp》

我們拿到了數據,而且經由過程onBack函數將他輸出到了掌握台上!

總結

  1. jsonp是一種跨域計劃,他應用script標籤沒有跨域限定的特性,經由過程script標籤的的src屬性發送GET要求。
  2. 能夠經由過程前後端商定一個字段名,比方callback,來通報一個函數名,從而使得前端能夠運用對應的callback函數,拿到數據,處置懲罰數據。

jsonp和cors比較

  1. CORS與JSONP的運用目標雷同,然則比JSONP更壯大。
  2. JSONP只支撐GET要求,CORS支撐一切範例的HTTP要求。JSONP的上風在於支撐老式瀏覽器,以及能夠向不支撐CORS的網站要求數據。

同源戰略:同源戰略限定了一個源(origin)中加載文本或劇本與來自別的源(origin)中資源的交互體式格局,這是一個用於斷絕潛伏歹意文件的主要平安機制。假如兩個頁面具有 雷同 的 協定(protocol),端口(假如指定),和 主機,那末這兩個頁面就屬於同一個源(origin)。

    原文作者:holyZhengs
    原文地址: https://segmentfault.com/a/1190000015450909
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞