如何解決ajax跨域問題(轉)

?

由 于此前很少寫前端的代碼(哈哈,不合格的程序員啊),最近項目中用到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")@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.congmo.net/blog/2012/06/27/ajax-cross-domain/

?

轉載于:https://www.cnblogs.com/weiwang/p/6952689.html

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

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

相關文章

mysql并發錯誤_又談php+mysql并發數據出錯問題

最近,項目中的所有crond定時盡量取消,改成觸發式。比如每日6點清理數據。原來的邏輯,寫一個crond定時搞定現在改為觸發式6點之后第一個玩家/用戶 進入,才開始清理數據。出現了一個問題1 如何確保第一個玩家觸發?updat…

leetcode 621. 任務調度器(貪心算法)

給你一個用字符數組 tasks 表示的 CPU 需要執行的任務列表。其中每個字母表示一種不同種類的任務。任務可以以任意順序執行,并且每個任務都可以在 1 個單位時間內執行完。在任何一個單位時間,CPU 可以完成一個任務,或者處于待命狀態。 然而&…

英國腦科學領域_來自英國A級算法崩潰的數據科學家的4課

英國腦科學領域In the UK, families, educators, and government officials are in an uproar about the effects of a new algorithm for scoring “A-levels,” the advanced level qualifications used to evaluate students’ knowledge of specific subjects in preparati…

MVC發布后項目存在于根目錄中的子目錄中時的css與js、圖片路徑問題

加載固定資源js與css <script src"Url.Content("~/Scripts/js/jquery.min.js")" type"text/javascript"></script> <link href"Url.Content("~/Content/css/shop.css")" rel"stylesheet" type&quo…

telegram 機器人_學習使用Python在Telegram中構建您的第一個機器人

telegram 機器人Imagine this, there is a message bot that will send you a random cute dog image whenever you want, sounds cool right? Let’s make one!想象一下&#xff0c;有一個消息機器人可以隨時隨地向您發送隨機的可愛狗圖像&#xff0c;聽起來很酷吧&#xff1…

判斷輸入的字符串是否為回文_刷題之路(九)--判斷數字是否回文

Palindrome Number問題簡介&#xff1a;判斷輸入數字是否是回文,不是返回0,負數返回0舉例:1:輸入: 121輸出: true2:輸入: -121輸出: false解釋: 回文為121-&#xff0c;所以負數都不符合3:輸入: 10輸出: false解釋: 倒序為01&#xff0c;不符合要求解法一&#xff1a;這道題比較…

python + selenium 搭建環境步驟

介紹在windows下&#xff0c;selenium python的安裝以及配置。1、首先要下載必要的安裝工具。 下載python&#xff0c;我安裝的python3.0版本,根據你自己的需要安裝下載setuptools下載pip(python的安裝包管理工具) 配置系統的環境變量 python,需要配置2個環境變量C:\Users\AppD…

VirtualBox 虛擬機復制

本文簡單講兩種情況下的復制方式 1 跨電腦復制 2 同一virtrul box下 虛擬機復制 ---------------------------------------------- 1 跨電腦復制 a虛擬機 是老的虛擬機 b虛擬機 是新的虛擬機 新虛擬機b 新建&#xff0c; 點擊下一步會生成 相應的文件夾 找到老虛擬機a的 vdi 文…

javascript實用庫_編寫實用JavaScript的實用指南

javascript實用庫by Nadeesha Cabral通過Nadeesha Cabral 編寫實用JavaScript的實用指南 (A practical guide to writing more functional JavaScript) Functional programming is great. With the introduction of React, more and more JavaScript front-end code is being …

數據庫數據過長避免_為什么要避免使用商業數據科學平臺

數據庫數據過長避免讓我們從一個類比開始 (Lets start with an analogy) Stick with me, I promise it’s relevant.堅持下去&#xff0c;我保證這很重要。 If your selling vegetables in a grocery store your business value lies in your loyal customers and your positi…

mysql case快捷方法_MySQL case when使用方法實例解析

首先我們創建數據庫表&#xff1a; CREATE TABLE t_demo (id int(32) NOT NULL,name varchar(255) DEFAULT NULL,age int(2) DEFAULT NULL,num int(3) DEFAULT NULL,PRIMARY KEY (id)) ENGINEInnoDB DEFAULT CHARSETutf8;插入數據&#xff1a;INSERT INTO t_demo VALUES (1, 張…

【~~~】POJ-1006

很簡單的一道題目&#xff0c;但是引出了很多知識點。 這是一道中國剩余問題&#xff0c;先貼一下1006的代碼。 #include "stdio.h" #define MAX 21252 int main() { int p , e , i , d , n 1 , days 0; while(1) { scanf("%d %d %d %d",&p,&e,&…

Java快速掃盲指南

文章轉自&#xff1a;https://segmentfault.com/a/1190000004817465#articleHeader22 JDK&#xff0c;JRE和 JVM 的區別 JVM&#xff1a;java 虛擬機&#xff0c;負責將編譯產生的字節碼轉換為特定機器代碼&#xff0c;實現一次編譯多處執行&#xff1b; JRE&#xff1a;java運…

xcode擴展_如何將Xcode插件轉換為Xcode擴展名

xcode擴展by Khoa Pham通過Khoa Pham 如何將Xcode插件轉換為Xcode擴展名 (How to convert your Xcode plugins to Xcode extensions) Xcode is an indispensable IDE for iOS and macOS developers. From the early days, the ability to build and install custom plugins ha…

leetcode 861. 翻轉矩陣后的得分(貪心算法)

有一個二維矩陣 A 其中每個元素的值為 0 或 1 。 移動是指選擇任一行或列&#xff0c;并轉換該行或列中的每一個值&#xff1a;將所有 0 都更改為 1&#xff0c;將所有 1 都更改為 0。 在做出任意次數的移動后&#xff0c;將該矩陣的每一行都按照二進制數來解釋&#xff0c;矩…

數據分析團隊的價值_您的數據科學團隊的價值

數據分析團隊的價值This is the first article in a 2-part series!!這是分兩部分的系列文章中的第一篇&#xff01; 組織數據科學 (Organisational Data Science) Few would argue against the importance of data in today’s highly competitive corporate world. The tech…

mysql 保留5位小數_小猿圈分享-MySQL保留幾位小數的4種方法

今天小猿圈給大家分享的是MySQL使用中4種保留小數的方法&#xff0c;希望可以幫助到大家&#xff0c;讓大家的工作更加方便。1 round(x,d)用于數據x的四舍五入, round(x) ,其實就是round(x,0),也就是默認d為0&#xff1b;這里有個值得注意的地方是&#xff0c;d可以是負數&…

leetcode 842. 將數組拆分成斐波那契序列(回溯算法)

給定一個數字字符串 S&#xff0c;比如 S “123456579”&#xff0c;我們可以將它分成斐波那契式的序列 [123, 456, 579]。 形式上&#xff0c;斐波那契式序列是一個非負整數列表 F&#xff0c;且滿足&#xff1a; 0 < F[i] < 2^31 - 1&#xff0c;&#xff08;也就是…

博主簡介

面向各層次&#xff08;從中學到博士&#xff09;提供GIS和Python GIS案例實驗實習培訓&#xff0c;以解決問題為導向&#xff0c;以項目實戰為主線&#xff0c;以科學研究為思維&#xff0c;不講概念&#xff0c;不局限理論&#xff0c;簡單照做&#xff0c;即學即會。 研究背…

自定義Toast 很簡單就可以達到一些對話框的效果 使用起來很方便

自定義一個layout布局 通過toast.setView 設置布局彈出一些警示框 等一些不會改變的提示框 很方便public class CustomToast {public static void showUSBToast(Context context) {//加載Toast布局 View toastRoot LayoutInflater.from(context).inflate(R.layout.toas…