国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

「跨域」利用node.js實踐前端各種跨域方式(上)

jaysun / 2688人閱讀

摘要:如果對你有幫助的話,歡迎一跨域首先我們在本地起一個服務器,用于接收客戶端的請求并作出回應。五跨域原理域想和域通信,通過中間頁面。即借助接收到了發來的消息,并給予回應跨域成功接下文跨域利用實踐前端各種跨域方式下

前言

常言道,"讀萬卷書,不如行萬里路"。技術的學習也是如此,唯有實踐才能更清楚的明白原理和加深印象,因此本文會利用node.js對前端的各種跨域方式進行實踐,強烈建議一步一步跟著做,相信你肯定會對跨域有更深層次的理解。而由于篇幅限制,本文只會貼出關鍵性的代碼,本系列總共分為上下篇。具體的代碼請移步我的Github。如果對你有幫助的話,歡迎 star ヾ(′?ω?`)?

一、cors 跨域

首先我們在本地起一個服務器,用于接收客戶端的請求并作出回應。

//目錄:cors/server.js

const http = require("http");

http.createServer(function (req, res) {
    //設置響應頭部
    res.writeHead(200, {"Content-Type": "text/plain"});
    res.write("This is a server page");
    res.end();
  }).listen(3333);
   console.log("server start!")

然后,開啟另一個服務,服務里加載一個html頁面,頁面對發出xhr請求,模擬瀏覽器對服務器的請求。

//目錄:cors/clientServer.js

const express = require("express");
const app = express();

app.use(express.static("./public"));
app.listen(3000)
console.log("client server start");

//目錄:cors/public/client.html

            const  content = document.getElementById("content");

            const xhr = new XMLHttpRequest();
            xhr.withCredentials = true;
            xhr.onload = function(){
                if(xhr.readyState == 4) {
                    if(xhr.status >= 200 && xhr.status <300 || xhr.status == 304) {
                        content.innerHTML = "Reuqest was success:" + xhr.responseText;
                        console.log("Request was success:", xhr.responseText);
                    }else {
                        content.innerHTML = "Reuqest was failed:" + xhr.status;
                        console.log("Request was failed:", xhr.status); 
                    }
                }
            }
            // xhr.open("get", "http://localhost:3000/client.html", true); //不跨域
            xhr.open("get", "http://localhost:3333", true); //跨域

            xhr.send();

分別運行兩個服務,測試3000和3333接口,發現只有跨域的時候,請求的頭部才會帶著origin字段。此時我們修改cors/server.js, 加上這行代碼:

    res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");

這行代碼代表服務器允許接收來自3000接口的請求,此時客戶端再次請求服務器,就能在用戶毫無感知的情況下完成跨域。

而此時如果想讓客戶端帶cookie請求呢?那么需要做以下工作:

1.cors/server.js 加上這行

    res.setHeader("Access-Control-Allow-Credentials", true);

2.cors/public/client.html 加上這行

xhr.withCredentials = true;

然后,你就會發現,客戶端會把當前域下的cookie一起發給服務器啦╮( ̄▽ ̄")╭

ps:注意cookie只能細分到域名下,不能細分到端口。即沒辦法設置一個cookie僅在localhost:xxxx下。盡管端口不同會被瀏覽器認為不同源。
二、jsonp跨域

通常為了減輕web服務器的負載,我們把js、css,img等靜態資源分離到另一臺獨立域名的服務器上,在html頁面中再通過相應的標簽從不同域名下加載靜態資源,而被瀏覽器允許,基于此原理,我們可以通過動態創建script,再請求一個帶參網址實現跨域通信。

下面這個例子采用jQuery中的ajax方法,與服務器端約定將數據回傳到回調函數中,比如本例中的callback=person,然后我們就可以從回調函數person里獲取服務器傳給瀏覽器的數據了。另外,jsonp的缺點就是只能采用get請求。

1.目錄:jsonp/server.js

const http = require("http");
const urllib = require("url");
const  httpdispatcher = require("httpdispatcher");
const dispatcher = new httpdispatcher();

const PORT = 1112;

function handleRequest(req, res) {
    try {
        console.log(req.url);

        dispatcher.dispatch(req, res);
    }catch(err) {
        console.log(err);
    }
}

const server = http.createServer(handleRequest);

dispatcher.onGet("/getPerson", function (req, res, next) {
  const data = {"name": "Jchermy", "company": "dog company"};
  const params = urllib.parse(req.url, true);

  if(params.query && params.query.callback) {
      let str = `${params.query.callback}(${JSON.stringify(data)})`;
      res.write(str);
      res.end();
  }else {
      res.write(JSON.stringify(data));
      res.end();
  }
})

server.listen(PORT, function () {
    console.log("server listening on http://localhost: %s", PORT);
  })

2.目錄:jsonp/client.js

const express = require("express");
const app = express();

app.use(express.static("./public"));
app.listen(1111);
console.log("client start");

3.目錄:jsonp/public/index.html




    
    
    
    index
    


    
    
姓名:
公司:

分別運行客戶端和服務端,點擊“獲取跨域數據的按鈕”,當前頁面(1111端口)就可以拿到1112端口的數據啦~~(●′ω`●)

三、document.domain + frame 跨域

此方案僅限主域相同,子域不同的跨域應用場景。

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

下面只是舉個例子幫助大家理解一下。

現在有兩個網址。百度知道和百度百科

https://zhidao.baidu.com/
https://baike.baidu.com/

在百度知道的網頁,寫下以下命令:

document.domain = "baidu.com";
const child= window.open("https://baike.baidu.com/");

在打開的百度百科的網頁,寫下以下命令:

document.domain = "baidu.com";

然后回到百度知道的網頁,就可以獲取到百度百科(子頁面)的元素啦:

const button = other.document.getElementById("search");

//
四、window.name+iframe 跨域
window.name屬性的獨特之處:name值在不同的頁面(甚至不同域名)加載后依舊存在,并且可以支持非常長的 name 值(2MB)。

在本地起兩個node服務,分別占用3333和4444。父頁面是:
1.window-name/public/index.html

          const proxy = function(url ,callback) {
                let status = 0;
                const iframe = document.createElement("iframe");

                iframe.src = url;

                iframe.onload = function(){
                    if(status === 1) {
                        callback(iframe.contentWindow.name);
                        destoryFrame();
                    } else if (status === 0) {
                        iframe.contentWindow.location = "http://localhost:4444/proxy.html";
                        status = 1;
                    }
                }

                document.body.appendChild(iframe);
          };
         

          function destoryFrame() {
              iframe.contentWindow.document.write("");
              iframe.contentWindow.close();
              document.body.removeChild(iframe);
          }

          proxy("http://localhost:3333/iframe.html", function(data) {
              alert(data);
          })

2.iframe 頁面是
window-name/public/iframe.html

    

3.還有一個代理頁面,跟父頁面同源。內容為空就好。目錄:/window-name/public/proxy.html

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

五、location.hash+iframe 跨域

原理:A域想和B域通信,通過中間頁面c。不同域之間通過location.hash來通信,而相同域之間直接通過js來通信。

實現:A域:a.html ----> B域:b.html ----> A域:c.html,a與b不同域只能通過hash值單向通信,b與c也不同域也只能單向通信,但c與a同域,所以c可通過parent.parent訪問a頁面所有對象。

目錄:location-hash/public/a.html




    
    
    
    a
    


    

目錄:location-hash/public/b.html




    
    
    
    b
    


    


目錄:location-hash/public/c.html

    

然后,我們通過node服務將a.html和c.html部署在同一個端口下,將b.html部署在另一個端口。

//location-hash/server1.js
app.use("/a.html", express.static(__dirname+"/public/a.html"));
app.use("/c.html", express.static(__dirname+"/public/c.html"));
app.listen(3333);

//location-hash/server2.js
app.use("/b.html", express.static(__dirname+"/public/b.html"));
app.listen(4444);

最后,我們分別將兩個服務跑起來。訪問localhost:3333可以看到彈窗。

即b.html借助c.html接收到了a.html發來的消息,并給予回應"hello admin",跨域成功~

接下文--->「跨域」利用node.js實踐前端各種跨域方式(下)

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/39966.html

相關文章

  • 跨域利用node.js實踐前端各種跨域方式

    摘要:如果對你有幫助的話,歡迎一跨域首先我們在本地起一個服務器,用于接收客戶端的請求并作出回應。五跨域原理域想和域通信,通過中間頁面。即借助接收到了發來的消息,并給予回應跨域成功接下文跨域利用實踐前端各種跨域方式下 前言 常言道,讀萬卷書,不如行萬里路。技術的學習也是如此,唯有實踐才能更清楚的明白原理和加深印象,因此本文會利用node.js對前端的各種跨域方式進行實踐,強烈建議一步一步跟著做...

    Lavender 評論0 收藏0
  • 跨域利用node.js實踐前端各種跨域方式(下)

    摘要:技術的學習也是如此唯有實踐才能更清楚的明白原理和加深印象,因此本文會利用對前端的各種跨域方式進行實踐,強烈建議一步一步跟著做,相信你肯定會對跨域有更深層次的理解。 前言 常言道,讀萬卷書,不如行萬里路。技術的學習也是如此,唯有實踐才能更清楚的明白原理和加深印象,因此本文會利用node.js對前端的各種跨域方式進行實踐,強烈建議一步一步跟著做,相信你肯定會對跨域有更深層次的理解。而由于篇...

    Jenny_Tong 評論0 收藏0
  • 前端相關大雜燴

    摘要:希望幫助更多的前端愛好者學習。前端開發者指南作者科迪林黎,由前端大師傾情贊助。翻譯最佳實踐譯者張捷滬江前端開發工程師當你問起有關與時,老司機們首先就會告訴你其實是個沒有網絡請求功能的庫。 前端基礎面試題(JS部分) 前端基礎面試題(JS部分) 學習 React.js 比你想象的要簡單 原文地址:Learning React.js is easier than you think 原文作...

    fuyi501 評論0 收藏0
  • 20170917 前端開發周報:JavaScript函數式編程、作用域和閉包

    摘要:用函數式編程對進行斷舍離當從業的老司機學會函數式編程時,他扔掉了的特性,也不用面向對象了,最后發現了真愛啊作用域和閉包作用域和閉包在里非常重要。旨在幫助非函數式編程的同學,能快速切入到函數式編程的理念。 1、用函數式編程對JavaScript進行斷舍離 當從業20的JavaScript老司機學會函數式編程時,他扔掉了90%的特性,也不用面向對象了,最后發現了真愛啊!!! https:/...

    tomener 評論0 收藏0
  • 20170917 前端開發周報:JavaScript函數式編程、作用域和閉包

    摘要:用函數式編程對進行斷舍離當從業的老司機學會函數式編程時,他扔掉了的特性,也不用面向對象了,最后發現了真愛啊作用域和閉包作用域和閉包在里非常重要。旨在幫助非函數式編程的同學,能快速切入到函數式編程的理念。 1、用函數式編程對JavaScript進行斷舍離 當從業20的JavaScript老司機學會函數式編程時,他扔掉了90%的特性,也不用面向對象了,最后發現了真愛啊!!! https:/...

    cyixlq 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<