㈠ 如何使用jsonp解決跨域問題
由 於此前很少寫前端的代碼(哈哈,不合格的程序員啊),最近項目中用到json作為系統間交互的手段,自然就伴隨著眾多ajax請求,隨之而來的就是要解決 ajax的跨域問題。本篇將講述一個小白從遇到跨域不知道是跨域問題,到知道是跨域問題不知道如何解決,再到解決跨域問題,最後找到兩種方法解決ajax 跨域問題的全過程。
不知是跨域問題
起 因是這樣的,為了復用,減少重復開發,單獨開發了一個用戶許可權管理系統,共其他系統獲取認證與授權信息,暫且稱之為A系統;調用A系統以B為例。在B系統 中用ajax調用A系統系統的介面(數據格式為json),當時特別困惑,在A系統中訪問相應的url可正常回返json數據,但是在B系統中使用 ajax請求同樣的url則一點兒反應都沒有,好像什麼都沒有發生一樣。這樣反反復復改來改去好久都沒能解決,於是求救同事,提醒可能是ajax跨域問 題,於是就將這個問題當做跨域問題來解決了。
知跨域而不知如何解決
知道問題的確切原因,剩下的就是找到解決問題的方法了。google了好久,再次在同事的指點下知道jQuery的ajax有jsonp這樣的屬性可以用來解決跨域的問題。
找到一種解決方式
現在也知道了怎樣來解決跨域問題,餘下的就是實現的細節了。實現的過程中錯誤還是避免不了的。由於不了解json和jsonp兩種格式的區別,也犯了錯誤,google了好久才解決。
首先來看看在頁面中如何使用jQuery的ajax解決跨域問題的簡單版:
復制代碼
$(document).ready(function(){
var url='http://localhost:8080/WorkGroupManagment/open/getGroupById"
+"?id=1&callback=?';
$.ajax({
url:url,
dataType:'jsonp',
processData: false,
type:'get',
success:function(data){
alert(data.name);
},
error:function(XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.status);
alert(XMLHttpRequest.readyState);
alert(textStatus);
}});
});
復制代碼
這樣寫是完全沒有問題的,起先error的處理函數中僅僅是alert(「error」),為了進一步弄清楚是什麼原因造成了錯誤,故將處理函數變 為上面的實現方式。最後一行alert使用為;parsererror。百思不得其解,繼續google,最終還是在萬能的stackoverflow找 到了答案,鏈接在這里。原因是jsonp的格式與json格式有著細微的差別,所以在server端的代碼上稍稍有所不同。
比較一下json與jsonp格式的區別:
json格式:
{
"message":"獲取成功",
"state":"1",
"result":{"name":"工作組1","id":1,"description":"11"}
}
jsonp格式:
callback({
"message":"獲取成功",
"state":"1",
"result":{"name":"工作組1","id":1,"description":"11"}
})
看出來區別了吧,在url中callback傳到後台的參數是神馬callback就是神馬,jsonp比json外面有多了一層,callback()。這樣就知道怎麼處理它了。於是修改後台代碼。
後台java代碼最終如下:
復制代碼
@RequestMapping(value = "/getGroupById")
public String getGroupById(@RequestParam("id") Long id,
HttpServletRequest request, HttpServletResponse response)
throws IOException {
String callback = request.getParameter("callback");
ReturnObject result = null;
Group group = null;
try {
group = groupService.getGroupById(id);
result = new ReturnObject(group, "獲取成功", Constants.RESULT_SUCCESS);
} catch (BusinessException e) {
e.printStackTrace();
result = new ReturnObject(group, "獲取失敗", Constants.RESULT_FAILED);
}
String json = JsonConverter.bean2Json(result);
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.print(callback + "(" + json + ")");
return null;
}
復制代碼
注意這里需要先將查詢結果轉換我json格式,然後用參數callback在json外面再套一層,就變成了jsonp。指定數據類型為jsonp的ajax就可以做進一步處理了。
雖然這樣解決了跨域問題,還是回顧下造成parsererror的原因。原因在於盲目的把json格式的數據當做jsonp格式的數據讓ajax處理,造成了這個錯誤,此時server端代碼是這樣的:
復制代碼
@RequestMapping(value = "/getGroupById")
@ResponseBody
public ReturnObject getGroupById(@RequestParam("id") Long id,
HttpServletRequest request, HttpServletResponse response){
String callback = request.getParameter("callback");
ReturnObject result = null;
Group group = null;
try {
group = groupService.getGroupById(id);
result = new ReturnObject(group, "獲取成功", Constants.RESULT_SUCCESS);
} catch (BusinessException e) {
e.printStackTrace();
result = new ReturnObject(group, "獲取失敗", Constants.RESULT_FAILED);
}
return result;
}
復制代碼
至此解決ajax跨域問題的第一種方式就告一段落。
追加一種解決方式
追求永無止境,在google的過程中,無意中發現了一個專門用來解決跨域問題的jQuery插件-jquery-jsonp。
有第一種方式的基礎,使用jsonp插件也就比較簡單了,server端代碼無需任何改動。
來看一下如何使用jquery-jsonp插件解決跨域問題吧。
復制代碼
var url="http://localhost:8080/WorkGroupManagment/open/getGroupById"
+"?id=1&callback=?";
$.jsonp({
"url": url,
"success": function(data) {
$("#current-group").text("當前工作組:"+data.result.name);
},
"error": function(d,msg) {
alert("Could not find user "+msg);
}
});
㈡ 我的一個java請求,該如何設置別人就可以跨域訪問我的請求得到數據
一、通過jsonp跨域
在js中,我們直接用XMLHttpRequest請求不同域上的數據時,是不可以的。但是,在頁面上引入不同域上的js腳本文件卻是可以的,jsonp正是利用這個特性來實現的。
比如,有個a.html頁面,它裡面的代碼需要利用ajax獲取一個不同域上的json數據,假設這個json數據地址是http://example.com/data.php,那麼a.html中的代碼就可以這樣:
我們看到b頁面成功的收到了消息。
使用postMessage來跨域傳送數據還是比較直觀和方便的,但是缺點是IE6、IE7不支持,所以用不用還得根據實際需要來決定。
結語:
除了以上幾種方法外,還有flash、在伺服器上設置代理頁面等跨域方式,這里就不做介紹了。
以上四種方法,可以根據項目的實際情況來進行選擇應用,個人認為window.name的方法既不復雜,也能兼容到幾乎所有瀏覽器,這真是極好的一種跨域方法。
㈢ jsonp的跨域只能採用get請求方式解決嗎
可以。JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。它基於JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一個子集。 JSON採用完全獨立於語言的文本格式,但是也使用了類似於C語言家族的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。這些特性使JSON成為理想的數據交換語言。易於人閱讀和編寫,同時也易於機器解析和生成(網路傳輸速度快)。
㈣ 如何在java代碼中執行jsonp請求
首先你要知道jsonp工作原理,實質上也就是利用了一些旁門左道(瀏覽器對資源文件無限制的特點)來進行的跨域訪問,能共用的技術是http,所以在java里可以使用httpclient工具來發送http請求,並把請求做成jsonp的請求模樣就行了。
㈤ jsonp服務端怎麼寫java
JSON是數據格式,用在同源非同步請求的返回結果。 JSONP是一種跨域請求方式,其原理就是
㈥ java jsonp怎麼轉換成map
這個問題問得不對吧,JSONP是一種跨域技術,MAP是一種數據結構;兩者不可能轉換
㈦ 為什麼已經用了jsonp了,還是存在跨域問題
使用jsonp解決跨域問題,不僅需要前端來改代碼,還需要後端來設置
㈧ jsonp返回的數據是什麼格式
jsonp主要是為了解決跨域訪問問題而產生的,其返回的數據格式一般就是一個js腳本,這個腳本有以下特點:
返回的js腳本通常是服務端動態生成的。
整個腳本通常有且僅有一條語句,且是一個函數調用。
腳本中調用到的函數,是頁面上存在的一個函數,其函數名通過get參數傳遞給服務端,服務端再將其回寫到js腳本中。
函數的參數,是服務端處理後的結果數據,以json格式直接寫在腳本中。這也是jsonp得名的由來。
因為,ajax是不允許跨域訪問的,所以要從其他站點獲取數據時,就需要經過一些特殊的手段才行,jsonp就是一種成本比較低的手段(此外還有服務端代理等方式)。jsonp主要是利用了<script><img><iframe>標簽可以跨域訪問的特點。具體的步驟如下:
首先,在本地頁面上事先准備好一個用於接受返回數據的函數,比如:function showList(listdata){...};
其次,在需要的時點靜態或動態地創建一個標簽,比如:<script type="text/javascript" src="http://another.website/jsonp_call?arg1=xx&arg2=xx&callback=showList"></script>,其中:
another.website:是另外一個站點的域名或ip地址。
jsonp_call:是該站點提供的一個動態內容訪問的服務,可用php、java等任何技術實現。
arg1、arg2:是該服務所需要的參數
callback:是用於返回結果的回調函數名。
然後,another.website站點接收到這個jsonp_call的請求後,進行相應的處理,並將放回的結果封裝為一個js腳本,其內容類似這樣的形式:showList([{id:1,name:'a'}, {id:2,name:'b'}, ..., {id:n,name:'NNN'}]);
最後,結果返回到客戶端後,就會自動解析並執行這個showList函數。
這樣就完成了從「向其他站點發起請求」到「接收其他站點的應答數據」的整個過程,並且突破了ajax跨域訪問的限制。
㈨ java為什麼會有跨域問題
前言
相信大家在寫前端腳本的時候經常會遇到發送數據到後台的情況,但是由於瀏覽器的限制,不同域名之間的數據是不能互相訪問的,那前端怎麼和後端如何進行數據之間的交換呢?
JavaScript由於安全性方面的考慮,不允許頁面跨域調用其他頁面的對象,那麼問題來了,什麼是跨域問題?
答:這是由於瀏覽器同源策略的限制,現在所有支持JavaScript的瀏覽器都使用了這個策略。那麼什麼是同源呢?所謂的同源是指三個方面「相同」:
域名相同
協議相同
埠相同
下面就舉幾個例子來幫助更好的理解同源策略。
URL
說明
是否允許通信
http://www.a.com/a.js
http://www.a.com/b.js 同一域名 允許
http://www.a.com/a.js
http://www.b.com/a.js 不同域名 不允許
http://www.a.com:8000/a.js
http://www.a.com/b.js 同一域名不同埠 不允許
https://www.a.com/a.js
http://www.a.com/b.js 同一域名不同協議 不允許
在JAVA中處理跨域問題,通常有以下兩種常用的解決方法。
第一種解決方法
後台代碼在被請求的Servlet中添加Header設置:
Access-Control-Allow-Origin這個Header在W3C標准里用來檢查該跨域請求是否可以被通過,如果值為*則表明當前頁面可以跨域訪問。默認的情況下是不允許的。
在前端JS中需要向Servlet發出請求,請求代碼如下所示:
第二種解決方法
通過jsonp跨域請求的方式。JSONP和JSON雖然只有一個字母的區別,但是他們完全就是兩回事,很多人很容易把他們搞混。JSON是一種數據交換的格式,而JSONP則是一種非官方跨域數據交互協議。
首先來說一下前端JS是怎麼發送請求。代碼如下所示:
這里的callbackparam和success_jsonpCallback可以理解為發送的data數據的鍵值對,可以自定義,但是callbackparam需要和後台約定好參數名稱,因為後台需要獲取到這個參數裡面的值(即success_jsonpCallback)。
下面,最重要的來了,後台怎麼樣獲取和返回數據呢。代碼如下所示:
首先需要獲取參數名為callbackparam的值,這里獲取到的值就是「success_jsonpCallback」。然後將這個值加上一對小括弧。小括弧里放入你需要返回的數據內容,比如這里我返回一個JSON對象。當然你也可以返回其他對象,比如只返回一個字元串類型數據也可以。最後前端JS返回的數據就是這樣的:
瀏覽器會自動解析為json對象,這時候你只需要在success回調函數中直接用data.status就可以了。
㈩ 如何解決ajax跨域問題
1.通過中間過渡層解決跨域問題
(1)通過Web代理伺服器將不同域的應用統一通過代理伺服器進行隔離,所有的應用都在一個域名下面了。(比如apache,nginx等)
(2)跨域的安全限制都是指瀏覽器端來說的.伺服器端是不存在跨域安全限制的,所以通過本機伺服器端通過類似httpclient方式完成「跨域訪問」的工作。
2.通過<script>標簽解決跨域問題
注意:凡是擁有"src"這個屬性的標簽都擁有跨域的能力,比如<script>、<img>、<iframe>
示例:
前台腳本:
Java代碼
<script type="text/javascript">
var flightHandler = function(data){
alert('你查詢的航班結果是:票價 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 張。');
};
var url = "http://abc.com:8080/AjaxCrossDomain/data/data.jsp?code=CA1998&callback=flightHandler";
var script = document.createElement('script');
script.setAttribute('src', url);
document.getElementsByTagName('head')[0].appendChild(script);
</script>
後台data.jsp內容:
Java代碼
<%@ page language="java" pageEncoding="UTF-8"%>
<%
String callback = request.getParameter("callback");
StringBuilder builder = new StringBuilder();
builder.append(callback).append("({").append("\"code\": \"CA1998\",").append("\"price\": 1780,").append("\"tickets\": 5").append("});");
out.println(builder.toString());
%>
使用jquery的jsonp來實現跨域訪問,例子如下:
Java代碼
<script type="text/javascript">
$(function(){
$.ajax({
type: "get",
async: false,
url: "http://abc.com:8080/AjaxCrossDomain/jsonp/data.jsp",
dataType: "jsonp",
jsonp: "callback",
jsonpCallback:"flightHandler",
success: function(json){
alert('您查詢到航班信息:票價: ' + json.price + ' 元,余票: ' + json.tickets + ' 張。');
},
error: function(){
alert('fail');
}
});
});
</script>