校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > 深入淺析Jsonp解決ajax跨域問題

深入淺析Jsonp解決ajax跨域問題

熱門標簽:云呼外撥網絡電話系統 ai機器人電銷資源 越南河內地圖標注 個人怎樣在百度地圖標注地名 機器人電銷騙局揭秘 騰訊地圖標注位置能用多久 地圖標注項目怎么樣 超級大富翁地圖標注 硅語電話機器人公司

一、介紹

最近跨域問題比較多,而且自己剛好也看到這一塊,就總結了一下,關于JSONP的東西百度的話東西確實很多,很多人都是復制別人的,如此下去,其實找的資料就那么幾份,關鍵是我還看不懂,可能是能力問題吧,自己經過很多嘗試,所以總結了一下,終究還是弄懂了皮毛。注意一點是,這里是用Jsonp解決ajax的跨域問題,具體的實現其實不是ajax。

1、同源策略

瀏覽器有一個很重要的概念——同源策略(Same-Origin Policy)。所謂同源是指,域名,協議,端口相同。不同源的客戶端腳本(JavaScript、ActionScript)在沒明確授權的情況下,不能讀寫對方的資源。

2、JSONP

JSONP(JSON with Padding)是JSON的一種”使用模式”,可用于解決主流瀏覽器的跨域數據訪問的問題。由于同源策略,一般來說位于 server1.example.com 的網頁無法與不是 server1.example.com的服務器溝通,而 HTML 的script 元素是一個例外。利用 script> 元素的這個開放策略,網頁可以得到從其他來源動態產生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料并不是 JSON,而是任意的JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。

二、實踐

1、模擬跨域請求

在本機弄兩個tomcat,端口分別為8080,8888,也就滿足了非同源的條件,那么要是從一個端口發送ajax去獲取另外一個端口的數據,那么肯定會報跨域請求問題。

這里有兩個項目,分別是jsonp(8080),other(8888),在jsonp項目中index.jsp如下:

%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
html>
head>
title>Insert title here/title>
script type="text/javascript" src="js/jquery.min.js">/script>
script type="text/javascript">
function jsonp_fun(){
$.ajax({
url:'http://localhost:8888/other/index.jsp',
type:'post',
dataType:'text',
success:function(data){
console.log(data);
}
});
}
/script>
/head>
body>
input type="button" value="jsonp" onclick="jsonp_fun()"/>
/body>
/html>

other(8888)項目中index.jsp如下:// 因為jsp實際就是servlet,這里就用jsp代替servlet演示。

%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
html>
head>
title>Insert title here/title>
script type="text/javascript" src="js/jquery.min.js">/script>
/head>
body>
other domain
/body>
/html>

其實中上面看無非就是jsonp頁面中點擊按鈕ajax去獲取other頁面中的數據。

結果如下:chrome控制臺


XMLHttpRequest cannot load http://localhost:8888/other/index.jsp. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.

以上提示就是指跨域問題,不能從8080這個域去訪問8888域的資源。

2、利用script標簽去訪問other域的js文件

由于script>標簽的src是支持跨域請求的。最常見的就是CDN服務的應用啦,比如我項目中,如果想用jQuery,但是就沒有這個js文件,去下載要找很久,而且版本還不知道下的對不對,那么可以百度搜jquery cdn,我隨便找一個,比如bootstrap的cdn:http://www.bootcdn.cn/jquery/,有很多版本供你選擇,只要在項目中加上就行了,最大缺點的話就是你沒網的話,就引入不到啦。

2.1 在other根路徑創建js/other.js文件,內容如下:

alert("this is other(8888) js");

2.2 在jsonp/index.jsp中,加入script標簽,引入other的js

script type="text/javascript" src="http://localhost:8888/other/js/other.js">/script>

進入http://localhost:8080/jsonp/index.jsp,會立馬彈出alert,表示引入的js文件自動執行了,跨域請求js成功。

2.3 同樣的,直接引用,會立馬執行立馬的alert,那么在other.js中寫函數,同樣jsonp/index.jsp中也能調用到,這點就不演示了,項目開發中大多都是這樣做的,頁面與js/css分離。

2.4 另外說明一點,如果在other.js中有函數通過ajax調用8080中的東西,然后引入之后,調用這個函數,也是可以的,但是如果other.js中函數ajax調用8888的東西,引入之后,調用這個函數,同樣是跨域的。

3、script實現跨域請求

3.1 簡單模擬服務器返回數據

將jsonp/index.jsp改成如下:這里注意引入的other.js的位置,是在函數getResult之后的,如果在它之前的話,會提示函數不存在。js加載順序是從上開始,在之前調用沒創建的,不能成功。注意這里是指引入的js文件,如果是同一個js文件或者當前頁面的js中,先執行調用,然后再寫函數也是沒有問題的,但是如果先執行調用引入js文件中的函數,然后再引入js文件,就會提示函數不存在。

script type="text/javascript" src="js/jquery.min.js">/script>
script type="text/javascript">
function jsonp_fun(){
$.ajax({
url:'http://localhost:8888/other/index.jsp',
type:'post',
dataType:'text',
success:function(data){
console.log(data);
}
});
}
function getResult(data){
alert(data.result);
}
/script>
script type="text/javascript" src="http://localhost:8888/other/js/other.js">/script>

然后other.js

getResult({"result":"this is other domain's data"});

也就是在jsonp/index.jsp頁面寫好函數,然后引入其他域的js傳入參數去調用這個函數,這里的參數你可以先看做是其他域服務器的接口返回的數據。

刷新頁面,效果當然是

彈出alert框,this is other domain's data

3.2 模擬接口訪問

看到這里,你會不會還是想不懂,上面js弄啥的,傳個死的數據,有什么實際意義嗎?,其實script的src不僅可以接js的地址,還可以接servlet的地址,也就是http接口地址,所以接下來,懶得寫servlet,這里還是寫jsp當做接口,在other項目中新建other.jsp頁面,內容如下:

%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
%
String params = request.getParameter("params");
out.println("ajax cross success,the server receive params :"+params);
%>

內容很簡單,也就是接受一個params的參數,然后返回數據給調用者。

我們在jsonp/index.jsp中加上

script type="text/javascript" src="http://localhost:8888/other/other.jsp?params=fromjsonp">/script>

看到這個地址,你是不是很熟悉,不熟悉的證明你用servlet用蠢了,jsp也是servlet,流程就是頁面一加載的時候,script標簽就會去發送請求,然后返回數據。那么我們刷新頁面,看看效果。

Uncaught SyntaxError: Unexpected identifier

報錯了,如上,然后代碼有問題?No,點擊錯誤,你會看到請求的東西也打印出來了,就是提示錯誤,表示這個東西瀏覽器不認識,其實是script不認識啦。

還不明白,那么你去頁面加上如下內容,你看報不報錯!!肯定報錯

script type="text/javascript">
ajax cross success,the server receive params : jsonp_param
/script>

那么js不能解析,我們換一種思路,要是我們輸出的是JSON字符串或者調用當前頁面函數的字符串了,類似于3.1中返回的getResult({“result”:”this is other domain's data”});

所以改造一下,把other.jsp中的內容改成

%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
%
String params = request.getParameter("params");
//out.println("ajax cross success,the server receive params :"+params);
out.println("getResult({'result':'"+params+"'})");
%>

別忘了,之前jsonp/index.jsp中我們定義了,那么加入引用之后,依然記得getResult函數與引入函數的先后順序問題。

script type="text/javascript">
function getResult(data){
alert(data.result);
}
/script>
script type="text/javascript" src="http://localhost:8888/other/other.jsp?params=fromjsonp">/script>

刷新頁面,發現大工告成。

至此,大部分原理已經講完了,還有一個問題,這里服務器返回的是getResult(xxx),其中這里的xxx可以當做是經過接口的很多處理,然后塞進去的值,但是這個getResult這個函數名,調用方與其他域服務器這一方怎么約定這個名字是一致的了,況且很多公司自己做服務的,別的公司的開發人員去調用,難道每個人都去那么公司去約定調用函數的名字?怎么可能,所以有人就想出來了一種解決方案,當然不是我~~,其實也很簡單啦,也就是把回調的函數名字也一起傳過去不就行了,所以代碼如下:

script type="text/javascript" src="http://localhost:8888/other/other.jsp?params=fromjsonpcallback=getResult">/script>

other.jsp

%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
%
String params = request.getParameter("params");
String callback = request.getParameter("callback");
// 經過該接口一系列操作,然后得到data,將data返回給調用者
String data = "{'result':'"+params+"'}";
out.println(callback + "("+data+")");
%>

代碼很簡單,也就是傳遞一個回調函數的參數名,然后經過該接口一系列操作,將返回數據,塞到回調函數里面,調用端的函數就得到了該接口的數據,也就是類似于ajax中succsss:function(data),然后處理data一樣,這里的success回調函數,相當于上面的getResult函數。當然你也可以寫的優雅一點,比如:

function CreateScript(src) {
$("script>//script>").attr("src", src).appendTo("body")
}
function jsonp_fun(){
CreateScript("http://localhost:8888/other/other.jsp?params=fromjsonpcallback=getResult")
}

4、Jquery的JSONP

至此跨域請求的原理已經講清楚了,但是仍然還有一個問題,總覺得這樣用有點怪是不是,如果用jquery的話,調用就很簡單了,其實jquery底層實現也是拼了一個script,然后指定src這種方式,跟上面講的一樣,只是jquery封裝了一下,顯得更加優雅,跟ajax調用方式差不多,所以容易記,代碼如下:

script type="text/javascript">
function getResult(data){
alert("through jsonp,receive data from other domain : "+data.result);
}
function jsonp_fun(){
$.ajax({
url:'http://localhost:8888/other/other.jsp',
type:'post',
data:{'params':'fromjsonp'},
dataType: "jsonp",
jsonp: "callback",//傳遞給請求處理程序或頁面的,用以獲得jsonp回調函數名的參數名(一般默認為:callback)
jsonpCallback:"getResult",//自定義的jsonp回調函數名稱,默認為jQuery自動生成的隨機函數名,也可以不寫這個參數,jQuery會自動為你處理數據
success: function(data){
},
error: function(){
alert('fail');
}
});
}
/script>
body>
input type="button" value="jsonp" onclick="jsonp_fun()"/>
/body>

這里的jsonCallback,回調函數設置為getResult,那么返回后會先調用getResult函數中的代碼,再調用success函數中的代碼,一般情況下,不用定義getResult函數,同樣jsonCallback不需要設置,那么就只執行success中的代碼,也就跟平時的ajax一樣用啦。

所以實際工作用法如下:

function jsonp_fun(){
$.ajax({
url:'http://localhost:8888/other/other.jsp',
type:'post',
data:{'params':'fromjsonp'},
dataType: "jsonp",
jsonp: "callback",//傳遞給請求處理程序或頁面的,用以獲得jsonp回調函數名的參數名(一般默認為:callback)
success: function(data){
alert("through jsonp,receive data from other domain : "+data.result);
},
error: function(){
alert('fail');
}
});
}
%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
%
String params = request.getParameter("params");
String callback = request.getParameter("callback");
// 經過該接口一系列操作,然后得到data,將data返回給調用者
String data = "{\"result\":\""+params+"\"}";
out.println(callback + "("+data+")");
%>

這里沒有指定jsonpCallback,實際上jquery底層拼裝了一個函數名,當然生成函數規則就沒研究了。

補充:

1、ajax和jsonp這兩種技術在調用方式上“看起來”很像,目的也一樣,都是請求一個url,然后把服務器返回的數據進行處理,因此jquery和ext等框架都把jsonp作為ajax的一種形式進行了封裝;

2、但ajax和jsonp其實本質上是不同的東西。ajax的核心是通過XmlHttpRequest獲取非本頁內容,而jsonp的核心則是動態添加script>標簽來調用服務器提供的js腳本。

3、所以說,其實ajax與jsonp的區別不在于是否跨域,ajax通過服務端代理一樣可以實現跨域,jsonp本身也不排斥同域的數據的獲取。

4、還有就是,jsonp是一種方式或者說非強制性協議,如同ajax一樣,它也不一定非要用json格式來傳遞數據,如果你愿意,字符串都行,只不過這樣不利于用jsonp提供公開服務。

以上內容是小編給大家介紹的Jsonp解決ajax跨域問題的相關資料,希望對大家有所幫助!

您可能感興趣的文章:
  • 原生JavaScript實現AJAX、JSONP
  • JavaScript用JSONP跨域請求數據實例詳解
  • 使用jsonp完美解決跨域問題
  • 原生js的ajax和解決跨域的jsonp(實例講解)

標簽:洛陽 舟山 海南 林芝 邢臺 鄭州 內蒙古 遼源

巨人網絡通訊聲明:本文標題《深入淺析Jsonp解決ajax跨域問題》,本文關鍵詞  深入,淺析,Jsonp,解決,ajax,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《深入淺析Jsonp解決ajax跨域問題》相關的同類信息!
  • 本頁收集關于深入淺析Jsonp解決ajax跨域問題的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    国产一区二区在线免费观看| 不卡电影免费在线播放一区| 这里只有精品视频在线观看| 麻豆精品在线看| 精品国产三级a在线观看| 六月丁香综合在线视频| 精品国产91久久久久久久妲己| 美女视频免费一区| 国产亚洲人成网站| 色综合久久综合网欧美综合网| 亚洲高清在线精品| 欧美一区二区啪啪| 成人一区二区三区在线观看| 亚洲视频免费在线| 欧美精品高清视频| 性做久久久久久久久| 加勒比av一区二区| 国产精品欧美一区喷水| 在线视频你懂得一区二区三区| 五月婷婷欧美视频| 日韩精品一区二区三区视频| av亚洲精华国产精华精| 亚洲电影一区二区| 亚洲精品在线三区| 色综合天天做天天爱| 奇米色777欧美一区二区| 国产精品无遮挡| 欧美日韩成人在线| 处破女av一区二区| 久久综合九色欧美综合狠狠| 亚洲精品在线电影| 激情综合色播激情啊| 亚洲精品成人少妇| 久久精品视频免费| 91精品国产一区二区三区蜜臀| 国产精品亚洲综合一区在线观看| 亚洲第一电影网| 国产精品情趣视频| 国产成人aaa| 久久se精品一区二区| 亚洲最新视频在线播放| 亚洲国产精华液网站w| 欧美高清激情brazzers| 91视视频在线观看入口直接观看www | 国产成人精品影视| 天堂一区二区在线免费观看| 中文字幕精品三区| 精品久久久久久久人人人人传媒 | 国产麻豆精品95视频| 亚洲成人先锋电影| 一色屋精品亚洲香蕉网站| 成人久久视频在线观看| 日韩影院免费视频| 欧美一区二区三区在线| 91丝袜国产在线播放| 国产精品1区2区| 五月激情六月综合| 久久精品一二三| 在线播放欧美女士性生活| 成人理论电影网| 国产乱码一区二区三区| 久久精品99国产精品日本| 亚洲国产综合色| 一区二区三区四区在线| 国产精品久久精品日日| 国产日韩欧美亚洲| 久久久99精品免费观看不卡| 欧美成人精精品一区二区频| 91精品国产日韩91久久久久久| 在线这里只有精品| 在线亚洲欧美专区二区| 91麻豆免费看片| 成人综合婷婷国产精品久久蜜臀| 老司机午夜精品| 亚瑟在线精品视频| 日韩和欧美一区二区三区| 一区二区三区欧美| 日韩欧美高清dvd碟片| 欧美日韩精品一区视频| 日韩午夜av电影| 亚洲精品一区二区三区精华液| 欧美一区二区网站| 欧美一区二区视频在线观看| 欧美精品日韩综合在线| 欧美三级日韩三级| 9191久久久久久久久久久| 欧美理论在线播放| 欧美在线|欧美| 91精品国产综合久久香蕉麻豆| 972aa.com艺术欧美| 成人一级片网址| 在线精品视频一区二区| 欧美精品电影在线播放| 91网站最新地址| 91视频免费播放| 欧美色国产精品| 日韩欧美亚洲一区二区| 欧美一区二区二区| 久久久国产精品麻豆| 久久午夜老司机| 国产精品成人在线观看| 一区二区三区精品| 老司机精品视频线观看86| 日韩1区2区日韩1区2区| 国产精品99久久久| av资源站一区| 国产一区二区导航在线播放| 日韩av午夜在线观看| 亚洲国产精品一区二区久久| 欧美xxxxx裸体时装秀| 91视频在线观看| 99精品久久只有精品| 欧美日本韩国一区二区三区视频| 久久精品免费在线观看| 亚洲免费观看视频| 亚洲综合久久久久| 久久av老司机精品网站导航| 91亚洲精华国产精华精华液| 欧美日韩国产一二三| 日韩亚洲欧美一区| 国产农村妇女精品| 1000精品久久久久久久久| 亚洲18色成人| 免费三级欧美电影| 国产成人在线视频播放| 久久先锋影音av鲁色资源| 午夜欧美在线一二页| 欧美日韩一区二区三区在线 | 欧美系列日韩一区| 亚洲男同1069视频| 国产成人在线视频播放| 中文字幕国产一区| 韩国女主播一区| 久久夜色精品国产噜噜av| 亚洲女人小视频在线观看| 色综合中文字幕| 国产三级三级三级精品8ⅰ区| 久久国产精品色| 日韩一区二区三区在线观看 | 精品对白一区国产伦| 日韩成人一级片| 欧美少妇bbb| 国产精品久久国产精麻豆99网站| 国产成人夜色高潮福利影视| 日韩精品一区二区三区视频播放 | 亚洲你懂的在线视频| 成人黄色大片在线观看| 中文字幕日本乱码精品影院| 成人免费看片app下载| 亚洲欧美怡红院| 国产成人精品影视| 国产精品系列在线| 91国模大尺度私拍在线视频| 亚洲精品视频在线观看网站| 成人国产精品免费网站| 久久婷婷色综合| 国产91色综合久久免费分享| 国产精品免费人成网站| 成人动漫一区二区三区| 亚洲综合无码一区二区| 欧美一a一片一级一片| 欧美bbbbb| 26uuu精品一区二区三区四区在线| 国产99久久久国产精品潘金| 欧美国产禁国产网站cc| av中文字幕不卡| 日韩成人av影视| 精品国产乱码久久久久久图片 | 国产精品你懂的在线欣赏| 99视频一区二区| 亚洲第一狼人社区| 91精品欧美综合在线观看最新| 国产激情视频一区二区在线观看| 久久久久国产精品免费免费搜索| 91免费国产在线| 亚洲成人午夜影院| 国产天堂亚洲国产碰碰| 91香蕉视频mp4| 国产综合一区二区| 亚洲精品ww久久久久久p站| 欧美卡1卡2卡| av一区二区三区黑人| 亚洲国产精品久久久男人的天堂| 久久久久99精品一区| a4yy欧美一区二区三区| 另类欧美日韩国产在线| 欧美一区二区日韩| 一本大道av一区二区在线播放| 九色综合国产一区二区三区| 国产欧美日韩另类视频免费观看 | 欧美探花视频资源| 秋霞国产午夜精品免费视频| 日本一区二区三区在线观看| 在线成人小视频| 国产精品一色哟哟哟| 日韩精彩视频在线观看| 欧美极品xxx| 337p日本欧洲亚洲大胆精品| 欧美片网站yy| 成人国产一区二区三区精品|