Ⅰ 如何解決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>轉載
Ⅱ 解決瀏覽器ajax請求本地文件報錯問題
近來在做自己的UI庫的時候,遇到一個問題,瀏覽器發送的ajax請求本地文件,會報跨域錯誤。報錯如下:
XMLHttpRequest cannot load file:///xxx
Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resource.
解決方案如下:chrome添加啟動參數:--allow-file-access-from-files ,這樣本地ajax請求就不會報跨域錯誤了。注意每個啟動參數「--」之前要有空格隔開。
做法:
找到谷歌瀏覽器啟動程序exe,發送快捷方式到桌面,在桌面右擊谷歌瀏覽器,選擇屬性,點擊快捷方式選項卡,在目標欄位後添加啟動參數:--allow-file-access-from-files,修改完成後點擊確定即可。重啟瀏覽器就不會報錯了。
具體操作如下圖:
Ⅲ 如何解決ajax跨域問題
找到一種解決方式
現在也知道了怎樣來解決跨域問題,餘下的就是實現的細節了。實現的過程中錯誤還是避免不了的。由於不了解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);
}
});
至此兩種解決跨域問題的方式就全部介紹完畢。
Ⅳ ajax請求請求數據緩存問題分析以及解決方案
在發送ajax請求的時候,為了保證每次的都與伺服器交互,就要傳遞一個參數每次都不一樣,這里就用了時間戳
大家在系統開發中都可能會在js中用到ajax或者dwr,因為IE的緩存,使得我們在填入相同的值的時候總是使用IE緩存
什麼是Ajax緩存原理?
Ajax在發送的數據成功後,會把請求的URL和返回的響應結果保存在緩存內,當下一次調用Ajax發送相同的請求時,它會直接從緩存中把數據取出來,這是為了提高頁面的響應速度和用戶體驗。當前這要求兩次請求URL完全相同,包括參數。這個時候,瀏覽器就不會與伺服器交互。
Ajax緩存的好處
這種設計使客戶端對一些靜態頁面內容的請求,比如圖片,css文件,js腳本等,變得更加快捷,提高了頁面的響應速度,也節省了網路通信資源。
Ajax緩存的不足
Ajax緩存雖然有上述的好處,但是如果通過Ajax對一些後台數據進行更改的時候,雖然數據在後台已經發生改變,但是頁面緩存中並沒有改變,對於相同的URL,Ajax提交過去以後,瀏覽器還只是簡單的從緩存中拿數據,這種情況當然就不行了。
四、解決Ajax緩存問題的方法
解決這個問題最有效的辦法是禁止頁面緩存,有以下幾種處理方法:
1、在ajax發送請求前加上 xmlHttpRequest.setRequestHeader(「Cache-Control」,」no-cache」);
2、在服務端加 header(「Cache-Control: no-cache, must-revalidate」);
3、在ajax發送請求前加上 xmlHttpRequest.setRequestHeader(「If-Modified-Since」,」0″);
4、在 Ajax 的 URL 參數後加上 "?fresh=" + Math.random(); //當然這里參數 fresh 可以任意取了
5、第五種方法和第四種類似,在 URL 參數後加上 "?timestamp=" + new Date().getTime();
6、用POST替代GET:不推薦
7、 jQuery 提供一個防止ajax使用緩存的方法:
javascript" language=" JavaScript ">
$.ajaxSetup ({
cache: false //close AJAX cache
});
8、修改load 載入的url地址,如在url 多加個時間參數就可以:
function loadEventInfoPage(eventId){
$.ajaxSetup ({
cache: true // AJAX cache 下面加上時間後load的頁面中的js、css圖片等都會重新載入,
//加上這句action會重新載入,但是js、css、圖片等會走緩存
});
$("#showEventInfo").load(ctx + "/custEvents/viewEvent.action", {"complaint.Id":eventId, "tt":(new Date()).getTime()},function(){})
}
9、設置html的緩存
Ⅳ 如何解決ajax跨域問題
1、什麼是跨域
跨域問題產生的原因,是由於瀏覽器的安全機制,JS只能訪問與所在頁面同一個域(相同協議、域名、埠)的內容(參考js的同源策略)。
但是我們項目開發過程中,經常會遇到在一個頁面的JS代碼中,需要通過AJAX去訪問另一個伺服器並返回數據,這時候就會受到瀏覽器跨域的安全限制了。
這里要注意,如果只是通過AJAX向另一個伺服器發送請求而不要求數據返回,是不受跨域限制的。瀏覽器只是限制不能訪問另一個域的數據,即不能訪問返回的數據,並不限制發送請求。
2、跨域解決方案
jsonp
Web頁面上調用js文件時不受是否跨域的影響,凡是擁有"src"這個屬性的標簽都擁有跨域的能力,比如<script>、<img>、<iframe>。那就是說如果要跨域訪問數據,就服務端只能把數據放在js格式的文件里。恰巧我們知道JSON可以簡潔的描述復雜數據,而且JSON還被js原生支持,所以在客戶端幾乎可以隨心所欲的處理這種格式的數據。然後客戶端就可以通過與調用腳本一模一樣的方式,來調用跨域伺服器上動態生成的js格式文件。客戶端在對JSON文件調用成功之後,也就獲得了自己所需的數據。這就形成了JSONP的基本概念。允許用戶傳遞一個callback參數給服務端,然後服務端返回數據時會將這個callback參數作為函數名來包裹住JSON數據,這樣客戶端就可以隨意定製自己的函數來自動處理返回數據了。
三步走:創建script、指定src,插入到文檔。
jQuery支持JSONP的調用。在另外的一個域名中指定好回調函數名稱,就可以用下面的形式來就載入JSON數據。
jQuery.getJSON(url + "&callback=?", function(data) {
alert(data.a + data.b);
});
服務端當然也要提供JSONP的支持,其實只要提供讀寫callback這個params就可以了。
跨域資源共享(CORS)
Cross-Origin Resource Sharing (CORS) 是W3c工作草案,它定義了在跨域訪問資源時瀏覽器和伺服器之間如何通信。CORS背後的基本思想是使用自定義的HTTP頭部允許瀏覽器和伺服器相互了解對方,從而決定請求或響應成功與否。
CORS與JSONP相比,更為先進、方便和可靠。
1、 JSONP只能實現GET請求,而CORS支持所有類型的HTTP請求。
2、 使用CORS,開發者可以使用普通的XMLHttpRequest發起請求和獲得數據,比起JSONP有更好的錯誤處理。
3、 JSONP主要被老的瀏覽器支持,它們往往不支持CORS,而絕大多數現代瀏覽器都已經支持了CORS。
對一個簡單的請求,沒有自定義頭部,要麼使用GET,要麼使用POST,它的主體是text/plain,請求用一個名叫Orgin的額外的頭部發送。Origin頭部包含請求頁面的頭部(協議,域名,埠),這樣伺服器可以很容易的決定它是否應該提供響應。
伺服器端對於CORS的支持,主要就是通過設置Access-Control-Allow-Origin來進行的。
Header set Access-Control-Allow-Origin *
為了防止XSS攻擊我們的伺服器, 我們可以限制域,比如
Access-Control-Allow-Origin: http://blog.csdn.net
很多服務都已經提供了CORS支持,比如 AWS 支持跨域資源分享功能CORS,向S3上傳不需要代理。
Ⅵ 如何解決ajax跨域請求失敗的問題
ajax跨域失敗,是因為js遵循同源規則,即不同域名下的js訪問是不被允許的(安全考慮),那麼如何解決,主要有三個方法,第一個是修改伺服器(如果是別人的伺服器,就沒辦法了,所以這個不多說,網上會有具體的操作),說一下客戶端就能解決的2個辦法,第一個,ajax返回數據,也就是dataType類型設置為jsonp,jsonp是專門為解決跨域問題而生的,具體用法自行網路,第二個方法,我最近也在用的,親測有效,就是先用自己伺服器後台執行curl,抓取目標伺服器上的文件,在用前端ajax獲取伺服器後台獲取到的目標伺服器文件結果即可
Ⅶ 如何解決ajax跨域問題
解決ajax跨域問題
方法1:
在伺服器端直接設置header內容:Access-Control-Allow-Origin:*
或者
Access-Control-Allow-Origin:允許訪問的url
這樣就可以直接請求到任何網站或者允許訪問的url
php程序這樣寫:
header('Access-Control-Allow-Origin:*');
或者
header('Access-Control-Allow-Origin:允許訪問的url ');
方法2:
在Nginx設置」頭信息「直接添加Access-Control-Allow-Origin:*的信息。
Ⅷ Ajax 跨域問題及其解決方案
主流的 前後端分離模式 下,當前端調用後台介面時,由於是在非同一個域下的請求,從而會引發 瀏覽器 的自我安全保護機制,最終結果是 介面成功請求並響應 ,但 前端不能正常處理該返回數據 。
因此,當 同時滿足 以下三個條件的情況下,就會出現跨域問題:
想要徹底解決跨域問題,只需要破壞以上三個條件的任一即可:
添加瀏覽器啟動參數: chrome --disable-web-security ,但是極不推薦這種解決方式。
Jsonp,全稱 JSON with Padding ,一種非官方的協議,而是一種約定;前端通過向後台發送 script 類型請求解決跨域,此時介面響應的 application/javascript 類型的數據會作為 callback 函數的參數進行處理。
所以,後台也需要做相應的處理。以 Java 為例,添加如下配置即可:
綜上, jsonp 請求存在以下幾個弊端:
用 Nginx 或 Apache 來代理調用方的請求( 客戶端變更為相對路徑請求,而非絕對路徑 ),此時對於瀏覽器來說,由於請求是同源的,因此就不存在跨域問題。
以 Java 應用為例,添加如下全局配置:
如果只想針對某個類下的介面,或者是某個具體的介面配置允許跨域,只需要在相應的地方添加註解 @CrossOrigin 即可。
如果配置了 nginx 作為代理伺服器,那麼只需要為 nginx 添加支持跨域請求即可:
Q1:瀏覽器在執行跨域請求時,是先執行後判斷,還是先判斷後執行?
A1:都有可能,這需要根據所發送的請求是 簡單請求 還是 非簡單請求 來判斷;如果是非簡單請求,瀏覽器每次在執行真正的請求之前,還會先發送一個 options 請求方式的預檢命令【 可設定緩存時長,取消每次請求都要預檢,提高效率,參考上面的服務端配置 】。關於兩種請求的區分及定義,參考下圖說明:
Q2:如果是允許帶( 被調用方 ) cookie 的跨域請求,此時服務端同樣配置為 Access-Control-Allow-Origin 等於 * ,前端是否還可以請求成功?
A2:不可以,此時要將 Access-Control-Allow-Origin 指定為 調用方 具體的域【 可以先取得調用方的域再動態配置,這樣就不存在多個域請求的限制問題 】,並且添加配置 Access-Control-Allow-Credentials 為 true 。