摘要:本文是在了解了瀏覽器的同源規則之后,學習了破解這個規則的一個簡單有效的方法。所以,年公司火狐的前身提出了瀏覽器的同源政策,目的是保護使用網站的用戶的信息安全。
本文是在了解了瀏覽器的同源規則之后,學習了破解這個規則的一個簡單有效的方法->JSONP。主要通過阮一峰老師的博客學習瀏覽器的同源規則
有這樣一個背景,如果你通過銀行的網站進行的取錢的交易,而其他用戶可以通過某個渠道獲得你在銀行網站的信息,那將是很可怕的。
所以,1995年NetScape公司(火狐的前身),提出了瀏覽器的同源政策,目的是保護使用網站的用戶的信息安全。那么何謂同源呢
協議相同
域名相同
端口號相同
不過,隨著互聯網的發展,有些時候我們需要破解同源,所以要先學習一下,古老而有效的JSONP方法。
瀏覽器如何向服務器提交數據有一天,程序員小白在自學,看到JSONP很牛,就向大神程序員小黑請教。小黑,小黑,這個JSONP是啥啊,感覺很牛( ⊙ o ⊙ )!。
小黑扶了扶500度的眼鏡,摸了一下頭頂的幾根頭發,若有所思的問小白。
小白啊,你說,瀏覽器怎么向服務器提交數據啊,比如說,你要付款這個情形。
form表單啊,我規定,我不用get請求。
您的賬戶余額是200
恩,還是不錯的啊,知道用POST發起請求。那你這提交完了之后,是不是還要在當前頁面刷新一下,才能看到余額啊。
……哎,是啊,不過我可以給你加一個iframe,就在當前頁面刷新
有什么反饋信息都在iframe顯示。
恩,也還行,不過你為啥要把總額200寫死在頁面呢,不應該動態從數據庫中獲得嗎
╮(╯▽╰)╭,稍等我改一哈
您的賬戶余額是&&&amount&&&
... button.addEventListener("click", (e) => { let n = amount.innerText let number = parseInt(n, 10) let newNumber = number - 1 amount.innerText = newNumber }
我用&&&amount&&&占位符表示總額,服務器端可以如下處理
var amount = fs.readFileSync("./db", "utf-8") //從db中讀取 string = string.replace("&&&amount&&&", amount) //把占位的數據換成真的數據 ... response.write(string)
恩,不錯,你再想想有沒有其他的方式也可以發送數據到服務器端啊,不用刷新頁面的那種
……還有其他的( ⊙ o ⊙ )??!
那我老黑我給你講講前輩程序員們試過的方法吧
//用圖片發起get請求 let image = document.createElement("img") image.src = "/pay" image.onload = function() { alert("打錢成功") amount.innerText = amount.innerText - 1 } image.onerror = function() { alert("打錢失敗") }
這種也是可以的,而且也會用提示給用戶,交互性還可以,不過只能發起GET請求,哈哈,我就是秀一下黑科技,很少用啦……
(@ο@) 哇~這也可以,小黑,你好棒,又長見識啦,不過還是沒給我講JSONP啊,你是不是忘了……
沒忘啦,不要著急,接下來,就給你好好講講這個JSONP
動態創建JS腳本發數據小白啊,你平常用的最多的是哪門語言啊
中文啊,英語不大好。
……我說編程的時候
呃呃,那個用的JavaScript多啊
好,那咱們就用js腳本發數據唄
//用js腳本發起請求 let script = document.createElement("script") script.src = "/pay" document.body.appendChild(script) script.onerror = function() { alert("failed") } ... //服務器端一般這么干 if(path === "/pay") { var amount = fs.readFileSync("./db", "utf8") var newAmount = amount - 1 fs.writeFileSync("./db", newAmount) response.setHeader("Content-Type", "application/javascript") response.statusCode = 200 response.write(` amount.innerText = amount.innerText - 1 `) response.end() }
以上是js腳本的大致意思,細節不要深究,明白就行。注意一下,添加script后,要記得document.body.appendChild(script)
不過,小黑啊,你這動態加上了script沒錯,可是你每次都往我的html底部加js,這破壞我的html啊
恩,小白啊,你思考能力還是可以的,目前確實有這個弊端,我給你處理一下
//用js腳本發起請求 let script = document.createElement("script") script.src = "/pay" document.body.appendChild(script) script.onload = function(e) { e.currentTarget.remove() //加載完了,就移除 } script.onerror = function(e) { alert("failed") e.currentTarget.remove() //加載完了,就移除 }
可以可以,小黑你這波操作可以的??熳屛乙娮R見識JSONP吧
好,這就給你變出來
?
button.addEventListener("click", (e) => { //用js腳本發起請求 let script = document.createElement("script") let functionName = "wushao" + parseInt((Math.random()*100000), 10) window[functionName] = function (result) { if (result === "success") { amount.innerText = amount.innerText - 1 } else { } } script.src = "http://想訪問的另一個網站:端口號/pay?callback=" + functionName document.body.appendChild(script) script.onload = function(e) { e.currentTarget.remove() } script.onerror = function(e) { alert("failed") e.currentTarget.remove() } })
ヾ(?`Д′?)黑神,你這跨度有點大,咋變了個大魔術。
O(∩_∩)O哈哈~,你讓我給你快點講的……,我給你講講細節吧
let functionName = "wushao" + parseInt((Math.random()*100000), 10) 使用一個隨機函數構建自己的函數名字,可以與服務器端代碼完美解耦,服務器端只需要,獲得查詢參數?callback=functionName 里面的functionName就可以了。
window[functionName] = function (result) { } 在window全局對象上添加functionName屬性,它的值是一個函數,當服務器端響應回來后,瀏覽器端的寫的函數的參數就是服務器端的success,我們就知道我的數據成功了。
//服務器端只需要這樣就可以了,不關心你寫的是什么函數名字 response.write(` ${query.callback}.call(undefined, "success") `)
哇,厲害啊,不過你又犯了一個相同的錯誤啦,哈哈,每次要把添加的全局對象的屬性去掉哦~
script.onload = function(e) { e.currentTarget.remove() delete window[functionName] } script.onerror = function(e) { alert("failed") e.currentTarget.remove() delete window[functionName] }
O(∩_∩)O哈!,這樣子就對了,小白啊,既然你學過jQuery,你試一試jQuery的寫法吧
(^o^)/~行,小黑,我也給你變一個
$.ajax({ url: "http://想訪問的另一個網站:端口號/pay", // The name of the callback parameter, as specified by the YQL service jsonp: "callback", // Tell jQuery we"re expecting JSONP dataType: "jsonp", // Work with the response success: function (response) { if(response === "success") { amount.innerText = amount.innerText - 1 } } })
哎呦,不錯呦,小白~
O(∩_∩)O哈哈~,我就是Google的 jquery jsonp
不過,這個可和ajax,沒啥關系啊,不明白為啥jquery為啥這么寫。
具體的代碼鏈接在============>傳送門
什么是JSONP呢請求方是一個網站(瀏覽器端),響應方是另一個網站(服務器端)
請求方動態的創建一個script腳本,src屬性是響應方的地址,同時傳遞一個查詢查參數?callback=functionName,一般functionName使用隨機函數構造。
響應方根據收到的查詢參數callback=functionName,去構造形如
2.1 functionName.call(undefined, "success")
2.2 或者直接functionName.("success")
這樣的響應。
瀏覽器收到響應之后,就會執行functionName.call(undefined, "success")或者functionName.("success")
然后,請求方就知道了他想要獲得的數據如何了。
這就是JSONP的原理
為什么JSONP不支持POST請求呢答曰:JSONP是動態創建的js腳本,這個方法只能發起GET請求,不能發起POST請求。
其他請求的話,用AJAX做嘍?
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107449.html
摘要:瀏覽器同源政策以及跨域同源是指協議相同域名相同端口相同。同源政策的目的,是為了保證用戶信息的安全,防止惡意的網站竊取數據。該協議不實行同源政策,只要服務器支持,就可以通過它進行跨源通信。參考文獻瀏覽器同源政策及其規避方法詳解跨域問題 瀏覽器同源政策以及JS跨域 同源是指協議相同、域名相同、端口相同。同源政策的目的,是為了保證用戶信息的安全,防止惡意的網站竊取數據。 同源策略主要限制下面...
摘要:扯了這么多,自然不是為了吹水,而是要為了引出前端開發的一個重要的知識點同源策略什么是同源策略出于保護用戶信息安全的目的,現在的瀏覽器都會實施同源策略這個政策,所謂同源策略指的是不同源的客戶端腳本在沒有明確授權情況下,不允許讀寫對方的資源。 導語你家的小孩帶了他的朋友來你們的家里玩,你家的小孩如果要在自家屋里拿玩具玩、拿東西吃你自然是不會阻止,但是如果你家小孩的朋友人品不行,亂拿東西吃、...
閱讀 1876·2021-09-24 09:48
閱讀 3220·2021-08-26 14:14
閱讀 1674·2021-08-20 09:36
閱讀 1460·2019-08-30 15:55
閱讀 3627·2019-08-26 17:15
閱讀 1425·2019-08-26 12:09
閱讀 606·2019-08-26 11:59
閱讀 3323·2019-08-26 11:57