淺談JSONP

這是我在13年初寫的文章,當時懵懵懂懂寫下了自己對JSONP的理解。

文章原文

博客 歡迎訂閱


提到JSONP,我當時在網上找了無數帖子也沒有看懂它。那些文章大同小異,都是講到JSONP原理以后就戛然而止,把我們這些初學者搞得云里霧里。所以,寫下這篇文章,希望對大家有幫助!

為什么要有JSONP

回答這個問題之前,大家先想想什么是AJAX,JSONP就是一種能夠解決AJAX辦不到的事情而存在的一種取數據的技術。什么事情是AJAX辦不到的呢?就是跨域!

跨域:顧名思義,就是當前網頁的地址和我們要取的數據地址不在一個域下。這是因為瀏覽器都有一個“同源策略”— 兩個頁面的域名必須在同域的情況下,才能允許通信。

怎么才算一個域呢?

相同域名,相同端口,相同協議(因為不是這里的重點,大家可以請教Google)

“同源策略”的意義:“同源策略”有效地阻止了一些危險行為,比如你進入www.aaa.com,同時瀏覽器又開了一個www.bbb.com,如果這個www.bbb.com是一個木馬網站,在沒有“同源策略”的情況下,它就可能嵌入一些代碼,來取得你在www.aaa.com的信息(因為這時兩個頁面是可以通信的) 。而正是因為有了“同源策略”,剛才可以通信的情況才不會發生。

“同源策略”帶來的麻煩:上面的例子是我們在不知情的情況下,保護我們的網絡安全的,但如果我們就是要讓www.aaa.com取得www.bbb.com上的數據,行不行呢?答:不行!還是因為”同源策略”!我們想從自己信任的網頁上取得數據都不行,這可怎么辦呢?

JSONP出現

在需要跨域通信的歲月里,一些卓越的前端工程師們想到了這個”作弊”的辦法來逃避”同源策略”。”同源策略”雖然很厲害,阻止了一個頁面到另一個頁面的通信,可是src指向的路徑它放過了,提到src,大家是不是想起了<script>?對,JSONP就是利用”同源策略”的這一”漏洞”來進行”作弊”的。(其實有src屬性的不止有<script>,還有<img><iframe>,而<iframe>也是能夠運用JSONP的)。

下面看看JSONP的原理:

JSONP:JSON with PaddingJSON大家這都知道,是一種數據通信格式,而”Padding”是什么意思,別急,往下看就知道了。

我們先舉一個簡單的例子:

www.aaa.com中:

<script type="text/javascript" src="http://www.bbb.com/abc.js"></script>
<script type="text/javascript">function abc(json){alert(json['name']); }
</script>

www.bbb.com/abc.js中:

abc({'name':'risker','age':24});

頁面會彈出risker,有感覺了么?

JSONP是這樣工作的:像前面所說的那樣,我們可以取到www.bbb.com/abc.js,里面是一個abc函數,這個函數也會被加載到www.aaa.com。加載完成后,就應該執行abc了,然后我們在www.aaa.com定義abc函數,這個函數里寫一些處理數據的語句。這樣其實就簡單地實現了跨域訪問數據了,這也就是JSONP的原理了。而JSON with Padding的意思,就是abc(json)中的json
abc({'name':'risker','age':24})

這個JSON對象被包在abc這個函數中當作參數來被處理,而JSON with Padding這個詞很形象地形容了這個過程。

JSONP的簡單實例

在網上能找到的JSON基本只是介紹到這里就完了,但是這讓初學者看不到一個實實在在的例子。所以下面才是這篇文章和其他網上介紹JSON文章不一樣的地方,我帶給大家一個例子!
大家一定對百度的自動搜索框有印象,它就是一個JSONP的實例:

62504685.jpg

先查看demo

分析一下:

1.分析數據地址回顧上面的例子,我們首先要知道數據的來源地址,就是上面的www.bbb.com/abc.js里的數據。在Chrome中查看Network。然后隨便在搜索框里輸入點什么,比如s,觀察Network里是不是多了東西,點開它,就是我們輸入“s”后傳回的數據了:

82372497.jpg

這個地址是http://suggestion.baidu.com/su?wd=S&p=3&cb=window.bdsug.sug&from=superpage&t=1365392859833 , 我們分析一下,wd后面是s,那就可以斷定百度定義wd是搜索的關鍵字,cb是一個回調函數,其他的對我們就不重要了。回調函數是我們取到數據要后執行的函數,相當于我們上面的abc函數。它是可以自己取名的。像http://suggestion.baidu.com/su?wd=S&p=3&cb=succ&from=superpage表示取到數據后執行succ函數:

28602969.jpg

這樣,我們的數據就包在了succ函數里做一個參數,再次證明了JSON with Padding 的原理。

2.做<script>標簽,其src指向數據地址:這是要動態生成的,不能把地址寫死,要不然取到的都是一樣的數據了。所以我們要動態生成<script>,動態指定src屬性:

var oScript = document.createElement('script');
oScript.src = 'http://suggestion.baidu.com/su?wd='+oTxt.value+'&amp;p=3&amp;cb=succ&amp;from=superpage';
document.body.appendChild(oScript);

3.不要以為這樣問題就解決了,F12一下,就看到生成了好多<script>!這是因為我們每輸入一個字符就動態生成一個<script>,造成了代碼冗余!解決一下:

if(oScript){
document.body.removeChild(oScript);
}

好,這樣,我們的搜索框效果就做好了,因為主要講JSONP部分的工作原理,就不做成百度下拉框那樣了,大家可以自己去布局。當然,真正的百度搜索框還要在此基礎上涉及事件的冒泡取消等等,就不是這里的重點了,不做闡述。

JSONP總結

  1. JSONP是為了傳數據而存在的技術。網頁之間的通信原本有AJAX就夠了,而AJAX因為瀏覽器“同源策略”面對跨域情況就束手無策了。JSONP就這樣被發明了,利用<script>src屬性不受“同源策略”的控制,“作弊”般地巧妙地逃過了瀏覽器的這一限制。

  2. JSONP方法本質是創建<script>標簽,其src指向我們的數據地址。地址后面附帶一個回調函數(名字一般是callback或者是別的什么,就看后臺給我們的是什么了,函數名是我們起的)。然后,聲明這個回調函數。這樣,只要一引入上面的<script>標簽,就相當于執行了那個回調函數。

  3. 雖然jQuery把JSONP內置在了AJAX里,但是我們一定要清楚,AJAX和JSONP是完全不一樣的,一定不要混淆!以后我會更新一篇介紹AJAX的文章的。

  4. 這里是前端和后臺的交匯之處,想要真正融會貫通,還要學學后臺的知識。我也是在學了PHP之后才把JSONP搞懂的。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/287608.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/287608.shtml
英文地址,請注明出處:http://en.pswp.cn/news/287608.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Asp.Net Core 7 preview 4 重磅新特性--限流

前言限流是應對流量暴增或某些用戶惡意攻擊等場景的重要手段之一&#xff0c;然而微軟官方從未支持這一重要特性&#xff0c;AspNetCoreRateLimit這一第三方庫限流庫一般作為首選使用&#xff0c;然而其配置參數過于繁多&#xff0c;對使用者造成較大的學習成本。令人高興的是&…

【計算機圖形學】實驗:C#.net環境下采用GDI+圖形特技處理案例教程

一、實驗目的 掌握在.net環境下對圖形特技的處理方法。 二、實驗準備 學習在.net環境下讀取圖像文件、改變顏色等基本知識。 三、實驗內容 在.net環境中實現對圖像的灰度化處理、柔化和銳化、底片濾鏡、淡入淡出以及浮雕、油畫和木刻等藝術效果。 四、實驗過程及步驟 (…

Windows之在終端打開當前目錄的命令

1 問題 Windows在終端打開當前目錄的命令 2 命令如下 1)、通過start命令 start . 2)、通過explorer命令 explorer .3 linux終端打開當前目錄命令如下 nautilus . 4 mac終端打開當前目錄命令如下 open .

孫鐘秀-《 操作系統教程 》(第4版)注釋(稿)

http://www.valleytalk.org/2014/12/30/%E5%AD%99%E9%92%9F%E7%A7%80-%E3%80%82%E3%80%8A-%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E6%95%99%E7%A8%8B-%E3%80%8B%EF%BC%88%E7%AC%AC4%E7%89%88%EF%BC%89%E6%B3%A8%E9%87%8A%EF%BC%88%E7%A8%BF/轉載于:https://www.cnblogs.com/zen…

Android中build target,minSdkVersion,targetSdkVersion,maxSdkVersion概念區分

如果開發的應用用戶較多&#xff0c;那么必須保證應用在多個版本不同的設備上能夠正確的運行。這就要求對各個版本比較熟悉&#xff0c;知道在什么版本中加入了什么新的功能或特性。但是Android的版本太多了&#xff0c;是個令人頭疼的問題。如果想了解Android的版本差異&#…

mysql交叉編譯 cmake_CMake交叉編譯配置

很多時候&#xff0c;我們在開發的時候是面對嵌入式平臺&#xff0c;因此由于資源的限制需要用到相關的交叉編譯。即在你host宿主機上要生成target目標機的程序。里面牽扯到相關頭文件的切換和編譯器的選擇以及環境變量的改變等&#xff0c;我今天僅僅簡單介紹下相關CMake在面對…

[python opencv 計算機視覺零基礎到實戰] 一 opencv的helloworld

前置條件 說明&#xff1a;本系列opencv實戰教程將從基礎到實戰&#xff0c;若只是簡單學習完python也可以通過該教程完成一般的機器學習編程&#xff1b;文中將會對很多python的基礎內容進行講解&#xff0c;但由于文章定位的原因將不會贅述過多的基礎內容&#xff0c;基礎內…

Android之用setColorFilter在ImageView上面覆蓋一層灰色的圖層

1 問題 在圖片上面覆蓋一層灰色的圖層 2 解決辦法 比如點擊圖片覆蓋黑色 imageView.setColorFilter(ContextCompat.getColor(context, R.color.picture_color_black_80), PorterDuff.Mode.SRC_ATOP); 然后點擊圖片還原回來 imageView.setColorFilter(ContextCompat.getCol…

【計算機圖形學】實驗:VB.net環境下的綜合繪圖與交互技術案例教程

一、實驗目的 掌握在.net環境下的繪圖軟件界面設計與交互技術。 二、實驗準備 學習在.net環境下的界面設計的一般原理與交互技術等基本知識。 三、實驗內容 將前7個實驗內容集成到一個界面下&#xff0c;如直線段、圓、矩形與曲線的繪制填充&#xff0c;以及對圖像的處理&…

IE8 兼容background-size的解決辦法

.bgpic { background-image:url(); background-size:cover; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src,sizingMethodscale); } 注意progid里面的src路徑是絕對路徑或是相對于頁面的路徑。? div class"bgpic"style"width:200px;height:1…

從頭開始敲代碼之《從BaseApplication/Activity開始》

轉載請注明出處王亟亟的大牛之路 其安易持&#xff0c;其未兆易謀&#xff1b;其脆易泮&#xff0c;其微易散。為之于未有&#xff0c;治之于未亂。合抱之木&#xff0c;生于毫末&#xff1b;九層之臺&#xff0c;起于壘土&#xff1b;千里之行&#xff0c;始于足下。為者敗之…

查缺補漏系統學習 EF Core 6 - 原始 SQL 查詢

推薦關注「碼俠江湖」加星標&#xff0c;時刻不忘江湖事這是 EF Core 系列的第五篇文章&#xff0c;上一篇文章盤點了 EF Core 中的幾種數據查詢方式。但是有有時候&#xff0c;我們可能無法用標準的 LINQ 方法完成查詢任務。或者編譯后的 LINQ 查詢&#xff0c;沒有我們想要的…

【python opencv 計算機視覺零基礎到實戰】二、 opencv文件格式與攝像頭讀取

一、學習目標 了解圖片的結構屬性了解如何捕獲視頻了解waitkey的使用方法 目錄 [python opencv 計算機視覺零基礎到實戰] 一、opencv的helloworld [【python opencv 計算機視覺零基礎到實戰】二、 opencv文件格式與攝像頭讀取] 一、opencv的helloworld [[python opencv 計…

python冒泡排序代碼完整_用Python寫冒泡排序代碼

python代碼實現冒泡排序代碼其實很簡單&#xff0c;具體代碼如下所示&#xff1a;代碼Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> 1 def bubbleSort(numbers):for j in xrange(len(numbers),-1,-1):for i in xra…

[C++]VS2005(VC8) 使用 Boost

測試環境&#xff1a;[1] Widnows XP Professional[2] Visual Studio 2005 Team Studio(VC8.0)[3] WinCvs 1.31. 下載 Boost透過 CVS 下載最新版 cvs -d:pserver:anonymousboost.cvs.sourceforge.net:/cvsroot/boost login [詢問密碼時&#xff0c;直接輸入 Enter 略過] cvs …

Android之編譯提示error: Apostrophe not preceded by

1 問題 as編譯提示錯誤如下 error: Apostrophe not preceded by 2 原因 字符串資源文件里面value包含一個單引號 <string name"key">Don t ....</string> 2 解決辦法 1) 加雙引號 <string name"key">"Don t ...."</s…

【ArcObject開發】實驗:ArcGIS Desktop開發方式入門基礎教程

一、實驗目的: 熟練掌握ArcGIS Desktop開發方式。 二、實驗準備: 學習ArcGIS Desktop定制步驟;熟悉VBA編程環境、Active DLL和Active EXE開發一般過程。 三、實驗內容: (1)描述在ArcGIS Desktop環境下定制窗體界面的一般步驟;(2)在VBA環境下編寫宏,實現圖層視圖…

C# WPF后臺動態添加控件(經典)

概述在Winform中從后臺添加控件相對比較容易&#xff0c;但是在WPF中&#xff0c;我們知道界面是通過XAML編寫的&#xff0c;如何把后臺寫好的控件動態添加到前臺呢&#xff1f;本節舉例介紹這個問題。這里要用到UniformGrid布局&#xff0c;UniformGrid 是一種橫向的網格分割、…

Android Button監聽的方式

Android Button的幾種監聽方式 1、一個Button對應一個監聽 1&#xff09;xml文件中綁定監聽 <Buttonandroid:id"id/btn_test"android:layout_width"match_parent"android:layout_height"wrap_content"android:text"test listener"a…

hdu 5441 (并查集)

題意&#xff1a;給你n個點&#xff0c;m條邊構成無向圖。q個詢問&#xff0c;每次一個值&#xff0c;求有多少條路&#xff0c;路中的邊權都小于這個值 a->b 和 b->a算兩種 思路&#xff1a;把權值從小到大排序&#xff0c;詢問從小到大排序&#xff0c;如果相連則用并查…