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

資訊專欄INFORMATION COLUMN

跨域解決方案大全

孫淑建 / 1614人閱讀

摘要:同源策略是處于對用戶安全的考慮,如果非同源就會受到以下限制不能讀取無法獲得請求不能發(fā)送但是事實(shí)是經(jīng)常需要借助非同源來提供數(shù)據(jù),所以就需要進(jìn)行跨域請求。

什么是跨域

注:本文完整示例地址
先來說一個(gè)概念就是同源,同源指的是協(xié)議,端口,域名全部相同

同源策略(Same origin policy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。可以說Web是構(gòu)建在同源策略基礎(chǔ)之上的,瀏覽器只是針對同源策略的一種實(shí)現(xiàn)。

同源策略是處于對用戶安全的考慮,如果非同源就會受到以下限制:

cookie不能讀取

dom無法獲得

ajax請求不能發(fā)送

但是事實(shí)是經(jīng)常需要借助非同源來提供數(shù)據(jù),所以就需要進(jìn)行跨域請求。

JSONP

JSONP是指JSON PaddingJSONP是一種非官方跨域數(shù)據(jù)交換協(xié)議,由于scriptsrc屬性可以跨域請求,所以JSONP利用的就是瀏覽器的這個(gè)“漏洞”,需要通信時(shí),動(dòng)態(tài)的插入一個(gè)script標(biāo)簽。請求的地址一般帶有一個(gè)callback參數(shù),假設(shè)需要請求的地址為http://localhost:666?callback=show,服務(wù)端返回的代碼一般是show(數(shù)據(jù))JSON數(shù)據(jù),而show函數(shù)恰恰是前臺需要用這個(gè)數(shù)據(jù)的函數(shù)。JSONP非常的簡單易用,自動(dòng)補(bǔ)全API利用的就是JSONP,下面來看一個(gè)例子:

// 前端請求代碼
function jsonp (callback) {
    var script = document.createElement("script"),
        url = `http://localhost:666?callback=${callback}`;
    script.setAttribute("src", url);
    document.querySelector("head").appendChild(script);
}
function show (data) {
    console.log(`學(xué)生姓名為:${data.name},年齡為:${data.age},性別為${data.sex}`);
}
jsonp("show");
// 后端響應(yīng)代碼
const student = {
    name: "zp1996",
    age: 20,
    sex: "male"
};
var callback = url.parse(req.url, true).query.callback;
res.writeHead(200, {
    "Content-Type": "application/json;charset=utf-8"
});
res.end(`${callback}(${JSON.stringify(student)})`);

JSONP雖說簡單易用,但是有一個(gè)很大問題,那就是JSONP只能進(jìn)行get請求

CORS

CORS(跨域資源共享)是由W3C制定的跨站資源分享標(biāo)準(zhǔn),可以讓AJAX實(shí)現(xiàn)跨域訪問。想要了解跨域的話,首先需要了解下簡單請求

請求方式為GET或者POST

假若請求是POST的話,Content-Type必須為下列之一:

application/x-www-form-urlencoded

multipart/form-data

text/plain

不含有自定義頭(類似于segmentfault自定義的頭X-Hit

對于簡單請求的跨域只需要進(jìn)行一次http請求:

function ajaxPost (url, obj, header) {
    return new Promise((resolve, reject) => {
        var xhr = new XMLHttpRequest(),
        str = "",
        keys = Object.keys(obj);
      for (var i = 0, len = keys.length; i < len; i++) {
        str += `${keys[i]}=${obj[keys[i]]}&`;
      }
      str = str.substring(0, str.length - 1);
      xhr.open("post", url);
      xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
      if (header instanceof Object) {
          for (var k in header) 
              xhr.setRequestHeader(k, header[k]);
      }
      xhr.send(str);
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
            resolve(xhr.responseText);
          } else {
            reject();
          }
        }
      }
    });
}
ajaxPost("http://localhost:666?page=cors", {
    name: "zp1996",
    age: 20,
    sex: "male"
})
.then((text) => { console.log(text); }, 
            () => { console.log("請求失敗"); });

// 后端處理
var postData = "";
// 注釋下,下面示例后臺代碼補(bǔ)充在此處
req.on("data", (data) => {
    postData += data;
});
req.on("end", () => {
    postData = querystring.parse(postData);
    res.writeHead(200, {
        "Access-Control-Allow-Origin": "*",
        "Content-Type": "application/json;charset=utf-8"
    });
    if (postData.name === student.name &&
        Number(postData.age) === student.age &&
        postData.sex === student.sex
         ) {
        res.end(`yeah!${postData.name} is a good boy~`);
    } else {
        res.end("No!a bad boy~");
    }
});

打開控制臺觀察可以發(fā)現(xiàn),Network只是發(fā)出了一次請求,但是對于非簡單請求來說,需要兩次http請求,在真正的請求之前需要進(jìn)行一次預(yù)請求,下圖是進(jìn)行一次預(yù)請求的請求/響應(yīng):

觀察響應(yīng)頭,可以發(fā)現(xiàn)需要多出了兩個(gè)響應(yīng)頭:

Access-Control-Allow-Headers,用來指明在實(shí)際的請求中,可以使用那些自定義的http請求頭。

Access-Control-Max-Age,用來指定此次預(yù)請求的結(jié)果的有效期,在有效期內(nèi)則不會發(fā)出預(yù)請求,有點(diǎn)像緩存的感覺。

當(dāng)然還有諸如好多這樣的響應(yīng)頭,請大家自行搜索了解,這里就不再過多介紹,下面來看下對于非簡單請求跨域的代碼處理:

// 前端請求代碼
ajaxPost("http://localhost:666?page=cors", {
    name: "zp1996",
    age: 20,
    sex: "male"
}, { "X-author": "zp1996" })
.then((text) => { console.log(text); }, 
            () => { console.log("請求失敗"); });

// 后端處理,補(bǔ)充在簡單請求代碼注釋處
if (req.method === "OPTIONS") {
    res.writeHead(200, {
        "Access-Control-Max-Age": 3000,
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Headers": "X-author",
        "Content-Type": "application/json;charset=utf-8"
    });    
    res.end();
    return void 0;        
} 
CSS Text Transformation

既然可以利用script的“漏洞”來進(jìn)行JSONP跨域,那么是不是也可以利用css樣式寫可以進(jìn)行跨域請求來進(jìn)行跨域呢?答案肯定是yes,利用css還有一個(gè)好處那就是,當(dāng)被注入攻擊腳本時(shí),css盡管被注入,也不會引起什么大的安全問題,頂多也就是把頁面的樣式給改變,而js被注入的話,cookie就有可能被盜取等一系列安全問題出現(xiàn)。大牛已經(jīng)將其做的非常完善,大家可以去star王集鵠(zswang)CSST,這里我就把我所理解給大家簡單的分享下:

// 前端代碼
const id = "csst",
    ele = document.querySelector(`#${id}`),
    head = document.querySelector("head");
function getStyle (ele, prop) {
    return getComputedStyle(ele, "").getPropertyValue(prop);
}
function loadCss (url) {
    return new Promise((resolve) => {
        const link = document.createElement("link");
         link.setAttribute("rel", "stylesheet");
        link.setAttribute("type", "text/css");
        link.setAttribute("href", url);
        ele.addEventListener("webkitAnimationStart", function () {
            resolve(getStyle(ele, "content"));
        });
        head.appendChild(link);
    });
}
loadCss(`http://localhost:666?page=data.css&id=${id}`).then((data) => {
    console.log(data);
});

// 后端代碼
function cssData (id) {
    return `
        @keyframes a{
            from{

            }
            to{
                color: red;
            }
        }
        #${id} {
            content: "這種是很好,但是只能傳輸文本啊";
            animation: a 2s;
        }
    `;
}
res.writeHead(200, {
    "Content-Type": "text/css"
});
res.end(cssData(query.id));

通過代碼可以看出這種實(shí)現(xiàn)方式是靠元素的content來拿接收到的數(shù)據(jù),所以傳輸?shù)闹荒苁俏谋?/strong>。至于為什么要返回動(dòng)畫?是因?yàn)椴焕脛?dòng)畫,無法來對css腳本加載進(jìn)行監(jiān)測,也就無法進(jìn)行回調(diào)(由于谷歌/火狐不支持linkonloadonreadychange,所以利用animationstart事件)。

window.postMessage

window.postMessage 是一個(gè)安全的跨源通信的方法。一般情況下,當(dāng)且僅當(dāng)執(zhí)行腳本的頁面使用相同的協(xié)議(通常都是 http)、相同的端口(http默認(rèn)使用80端口)和相同的 host(兩個(gè)頁面的 document.domain 的值相同)時(shí),才允許不同頁面上的腳本互相訪問。 window.postMessage 提供了一個(gè)可控的機(jī)制來安全地繞過這一限制,當(dāng)其在正確使用的情況下。

window.postMessage解決的不是瀏覽器與服務(wù)器之間的交互,解決的是瀏覽器不同的窗口之間的通信問題,可以做的就是同步兩個(gè)網(wǎng)頁,當(dāng)然這兩個(gè)網(wǎng)頁應(yīng)該是屬于同一個(gè)基礎(chǔ)域名。

// 發(fā)送端代碼
var domain = "http://localhost",
    index = 1,
    target = window.open(`${domain}/postmessage-target.html`);
function send () {
    setInterval(() => {
        target.postMessage(`第${index++}次數(shù)據(jù)發(fā)送`, domain);
    }, 1000);
}
send();
// 接受端代碼
沒有數(shù)據(jù)過來啊

上述代碼實(shí)現(xiàn)了向一個(gè)頁面向另一個(gè)發(fā)送數(shù)據(jù),但是這么寫往往有著一些“危險(xiǎn)”,需要知道的是,postMessage是向document對象中,網(wǎng)絡(luò)連接有時(shí)會很慢,可能會出現(xiàn)些問題,所以最好的方式是接受頁面已經(jīng)開始加載了,這時(shí)發(fā)送一個(gè)消息給發(fā)送端,發(fā)送端在開始向接收端發(fā)送數(shù)據(jù)。改進(jìn)下:

// 發(fā)送端添加代碼
window.addEventListener("message", (e) => {
    if (e.data === "ok")
        send();
    else 
        console.log(e.data);
});

// 接受端的head里面加上script標(biāo)簽
window.name

window.name 的美妙之處:name 值在不同的頁面(甚至不同域名)加載后依舊存在,并且可以支持非常長的 name 值(2MB)

這個(gè)方式我基本上沒有用過,所以沒有過多的發(fā)言權(quán),大家想了解這個(gè)技術(shù)的話,可以通過懌飛(圓心):使用 window.name 解決跨域問題,圓心大神解釋的非常透徹。

document.domain

將子域和主域的document.domain設(shè)為同一個(gè)主域
前提條件:

這兩個(gè)域名必須屬于同一個(gè)基礎(chǔ)域名

而且所用的協(xié)議,端口都要一致,否則無法利用document.domain進(jìn)行跨域

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/91077.html

相關(guān)文章

  • XMLHTTPRequest屬性、方法、事件大全&詳解。

    摘要:屬性方法事件整理大全。有嚴(yán)格安全限制。值描述將設(shè)為空字符串與設(shè)置為相同,是默認(rèn)類型實(shí)際上是。默認(rèn)值為空字符串只有當(dāng)為時(shí),對象上才有此屬性,此時(shí)才能調(diào)用,否則拋錯(cuò)。以下種情況下值都為空字符串請求未完成請求失敗。 XMLHTTPRequest屬性、方法、事件整理大全。 xhr 對象的方法 open(method:string, url:string, async?:boolean=tr...

    roadtogeek 評論0 收藏0
  • 【收藏干貨】axios配置大全

    摘要:一安裝利用安裝利用安裝直接利用引入二例子發(fā)送一個(gè)請求通過給定的來發(fā)送請求以上請求也可以通過這種方式來發(fā)送發(fā)送一個(gè)請求一次性并發(fā)多個(gè)請求當(dāng)這兩個(gè)請求都完成的時(shí)候會觸發(fā)這個(gè)函數(shù),兩個(gè)參數(shù)分別代表返回的結(jié)果三的可以通過配置來發(fā)送請求發(fā)送一 一、安裝 1、 利用npm安裝npm install axios --save 2、 利用bower安裝bower install axios --sav...

    import. 評論0 收藏0
  • 前端基礎(chǔ)入門

    摘要:手把手教你做個(gè)人火的時(shí)候,隨便一個(gè)都能賺的盆滿缽滿,但是,個(gè)人沒有服務(wù)端,沒有美工,似乎就不能開發(fā)了,真的是這樣的嗎秘密花園經(jīng)典的中文手冊。涵蓋前端知識體系知識結(jié)構(gòu)圖書推薦以及入門視頻教程,全的簡直不要不要的了。 JavaScript 實(shí)現(xiàn)點(diǎn)擊按鈕復(fù)制指定區(qū)域文本 html5 的 webAPI 接口可以很輕松的使用短短的幾行代碼就實(shí)現(xiàn)點(diǎn)擊按鈕復(fù)制區(qū)域文本的功能,不需要依賴 flash。...

    shinezejian 評論0 收藏0
  • 前端最實(shí)用書簽(持續(xù)更新)

    摘要:前言一直混跡社區(qū)突然發(fā)現(xiàn)自己收藏了不少好文但是管理起來有點(diǎn)混亂所以將前端主流技術(shù)做了一個(gè)書簽整理不求最多最全但求最實(shí)用。 前言 一直混跡社區(qū),突然發(fā)現(xiàn)自己收藏了不少好文但是管理起來有點(diǎn)混亂; 所以將前端主流技術(shù)做了一個(gè)書簽整理,不求最多最全,但求最實(shí)用。 書簽源碼 書簽導(dǎo)入瀏覽器效果截圖showImg(https://segmentfault.com/img/bVbg41b?w=107...

    sshe 評論0 收藏0
  • 【回顧九月份第二周】 前端你該知道的事兒

    摘要:順便一說,這首歌的原唱是秋田,中島當(dāng)年嗓子壞了,才有這歌。中文是直接翻譯來的,作曲是秋田。一部電影春夏秋冬又一春春夏秋冬又一春是由金基德執(zhí)導(dǎo),金英民吳英秀金基德主演的一部韓國電影。年月日于韓國上映。 原鏈接: http://bluezhan.me/weekly/#/9-2 1、web前端 Angular vs. React vs. Vue: A 2017 comparison 9 S...

    sixgo 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<