如何解決ajax跨域問題

原文:http://www.congmo.net/blog/2012/06/27/ajax-cross-domain/


跨域問題

起 因是這樣的,為了復用,減少重復開發,單獨開發了一個用戶權限管理系統,共其他系統獲取認證與授權信息,暫且稱之為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")@ResponseBodypublic 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);}
});
復制代碼

?

至此兩種解決跨域問題的方式就全部介紹完畢。


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

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

相關文章

spring bean創建細節

1) 對象創建: 單例/多例 scope"singleton", 默認值,即默認是單例【service/dao/工具類】 scope"prototype", 多例;【Action對象】 2) 什么時候創建? scope"prototype" 在用到對象的時候&#xff0c…

發送郵件程序報錯454 Authentication failed以及POP3和SMTP簡介

一、發現問題 在測試郵件發送程序的時候,發送給自己的QQ郵箱,程序報錯454 Authentication failed, please open smtp flag first。 二、解決問題 進入QQ郵箱——>設置——>賬戶——>POP3/IMAP/SMTP選擇——>開啟POP3/SMTP服務。 三、POP3和S…

MySQL數據庫是非關系_MySQL(數據庫)基礎知識、關系型數據庫yu非關系型數據庫、連接認證...

什么是數據庫?數據庫(Database):存儲數據的倉庫高效地存儲和處理數據的介質(介質主要是兩種:磁盤和內存)數據庫系統:DBS(Database System):是一種虛擬系統,將多種內容關聯起來的稱呼DBS DBMS DBDBMS&…

WPF 使用MahApps.Metro UI庫

http://www.cnblogs.com/happyyftk/p/6904766.html 本文示例源碼下載:MetroWPF 官方示例地址:http://mahapps.com/guides/quick-start.html 官方控件示例地址:http://mahapps.com/controls/ MahApps.Metro 項目源碼:https://githu…

SpringIOC容器-創建對象

SpringIOC容器,是spring核心內容。功能:創建對象,處理對象的依賴關系 IOC容器創建對象: 創建對象, 有幾種方式: 1) 調用無參數構造器 2) 帶參數構造器 3) 工廠創建對象 工廠類&…

java注釋搞笑圖案_搞笑的代碼注釋,那些有趣的程序員

發表于 2019-04-24 16:11:26 by 月小升搞笑/**** .::::.* .::::::::.* ::::::::::: F*CK YOU* ..:::::::::::* ::::::::::::* .::::::::::* ::::::::::::::..* ..::::::::::::.* ::::::::::::::::* ::::::::::::: .:::.* :::: ::::: .::::::::.* .:::: :::: .:::::::::::.* .::…

SpringIOC容器-對象依賴

1 概述 Spring中&#xff0c;如何給對象的屬性賦值? 【DI, 依賴注入】 1) 通過構造函數 2) 通過set方法給屬性注入值 3) p名稱空間 4) 自動裝配 5) 注解 1.1 通過構造函數 <!-- ###############對象屬性賦值############### --><!-- 1) 通過構造函數 --><be…

f5長連接策略

但是把這些短連接匯聚到一起&#xff0c;集中F5的設備上&#xff0c;通過F5與服務器建立平滑的長連接&#xff0c;就解決了不斷增大的并發連接。比如說前臺有15萬個并發連接&#xff0c;經過F5的優化&#xff0c;在服務器上只有不到5000個并發連接&#xff0c;而且在此過程中&a…

pdo-mysql_PHP: MySQL (PDO) - Manual

PDO::MYSQL_ATTR_USE_BUFFERED_QUERY(int)Если этот атрибут установлен в true вPDOStatement, MySQL-драйвербудет использовать буферизованные версии API MySQL.Если вы пишете пе…

Spring IOC容器【p名稱空間注入屬性值 】

# p 名稱空間給對象的屬性注入值(spring3.0以上版本才支持) 需要引入&#xff1a; xmlns:p"http://www.springframework.org/schema/p" 舉例 applicationContext.xml <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http…

Spring properties定義bean

2019獨角獸企業重金招聘Python工程師標準>>> Spring提供了豐富的標簽和注解來進行bean的定義&#xff0c;除此之外框架來提供了擴展機制讓使用可以通過properties來定義bean&#xff0c;與強大的標簽式和注解式的bean定義相比&#xff0c;properties提供的規則要簡單…

Spring IOC容器-自動裝配

1 autowire"byName" 根據名稱自動裝配&#xff0c;自動去IOC容器中找與屬性名同名的引用的對象&#xff0c;并自動注入。 <!-- ###############自動裝配############### --> <bean id"userDao" class"d_auto.UserDao"></bean&g…

linux下C++遍歷文件夾下的全部文件;Windows/Linux下C++批量修改文件名,批量刪除文件...

Linux下 C遍歷目錄下所有文件 1 rename(image_path.c_str(), image_path_new.c_str()); 2 remove(image_path_move.c_str()); 上述批量操作的代碼是在linux下的參數設置&#xff1a; rename的參數&#xff0c;image_path為原文件的路徑文件名&#xff0c;image_path_new為文件…

mongodb java 單例_Java單例MongoDB工具類

我經常對MongoDB進行一些基礎操作&#xff0c;將這些常用操作合并到一個工具類中&#xff0c;方便自己開發使用。沒用Spring Data、Morphia等框架是為了減少學習、維護成本&#xff0c;另外自己直接JDBC方式的話可以更靈活&#xff0c;為自己以后的積累留一個腳印。Java驅動版本…

Spring IOC容器-注解的方式

注解方式可以簡化spring的IOC容器的配置&#xff0c;但不利于后期維護&#xff0c;對象之間的依賴關系不能像xml文件一樣方便查閱&#xff0c;一目了然。 注解可以和XML配置一起使用。 使用注解步驟&#xff1a; 1&#xff09;先引入context名稱空間 xmlns:context"htt…

前端請求進化之路--從form表單到JSONP

簡單梳理前端請求的變遷史&#xff0c;著重對JSONP進行整理 請求演變 使用form表單提交請求&#xff0c;缺點是每次提交必定會刷新頁面在1基礎之上使用iframe進行局部刷新&#xff0c;用戶體驗得到一定優化動態創建圖片提交請求 注意請求與返回內容類型須一致每次必須返回圖片較…

Spring IOC容器-注解的方式【更簡化】

----更加簡化的版本 UserAction.java import javax.annotation.Resource;import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller;//Component("userAction") // 加入IOC容器//ComponentController // 控制層的組件…

hive安裝mysql驅動_Hadoop-2.6.0為基礎的Hive安裝

Hive安裝軟件需求與環境說明假設已經搭建好 Hadoop-2.6.0 環境&#xff0c;并能正常運行mysql 安裝軟件服務端&#xff1a;MySQL-server-5.5.16-1.rhel5.x86_64.rpm客戶端&#xff1a;MySQL-client-5.5.16-1.rhel5.x86_64.rpmhive安裝軟件&#xff1a;apache-hive-1.2.1-bin.ta…

視頻通信原理——NAT介紹

一&#xff1a;為什么需要NAT由于IP地址隨著互聯網的發展而逐漸稀缺&#xff0c;難以使得每臺主機都擁有一個公網上的IP地址&#xff0c;且并不是所有主機都需要一個公網上的地址&#xff0c;于是就有了NAT技術。NAT&#xff08;The IP Network Address Translator&#xff09;…

Oracle中執行存儲過程call和exec區別

在sqlplus中這兩種方法都可以使用&#xff1a; exec pro_name(參數1..); call pro_name(參數1..); 區別&#xff1a; 1. 但是exec是sqlplus命令&#xff0c;只能在sqlplus中使用&#xff1b;call為SQL命令&#xff0c;沒有限制. 2. 存儲過程沒有參數時,exec可以直接跟過…