必須是 jsonpCallback 而不是jsonpcallback
十年的和田網(wǎng)站建設經(jīng)驗,針對設計、前端、開發(fā)、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。網(wǎng)絡營銷推廣的優(yōu)勢是能夠根據(jù)用戶設備顯示端的尺寸不同,自動調(diào)整和田建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)公司從事“和田網(wǎng)站設計”,“和田網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。
代碼如下:
$.ajax({
url: ';tm=',
dataType: 'JSONP',
jsonpCallback: '_GroupMember_Callback',
success: function(json){
}
});
前言
相信大家在寫前端腳本的時候經(jīng)常會遇到發(fā)送數(shù)據(jù)到后臺的情況,但是由于瀏覽器的限制,不同域名之間的數(shù)據(jù)是不能互相訪問的,那前端怎么和后端如何進行數(shù)據(jù)之間的交換呢?
JavaScript由于安全性方面的考慮,不允許頁面跨域調(diào)用其他頁面的對象,那么問題來了,什么是跨域問題?
答:這是由于瀏覽器同源策略的限制,現(xiàn)在所有支持JavaScript的瀏覽器都使用了這個策略。那么什么是同源呢?所謂的同源是指三個方面“相同”:
域名相同
協(xié)議相同
端口相同
下面就舉幾個例子來幫助更好的理解同源策略。
URL
說明
是否允許通信
同一域名 ? ?允許 ?
不同域名 ? ?不允許 ?
同一域名不同端口 ? ?不允許 ?
同一域名不同協(xié)議 ? ?不允許 ?
在JAVA中處理跨域問題,通常有以下兩種常用的解決方法。
第一種解決方法
后臺代碼在被請求的Servlet中添加Header設置:
response.setHeader("Access-Control-Allow-Origin", "*");
PrintWriter out =null;
try
{
out = response.getWriter();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
out.print("{'status':'ok'}");
out.flush();
out.close();
Access-Control-Allow-Origin這個Header在W3C標準里用來檢查該跨域請求是否可以被通過,如果值為*則表明當前頁面可以跨域訪問。默認的情況下是不允許的。
在前端JS中需要向Servlet發(fā)出請求,請求代碼如下所示:
$.ajax({
url: "your url",
type:"get or post",
dataType:"json",
data:{
....
},
success:function(data){
...
}
第二種解決方法
通過jsonp跨域請求的方式。JSONP和JSON雖然只有一個字母的區(qū)別,但是他們完全就是兩回事,很多人很容易把他們搞混。JSON是一種數(shù)據(jù)交換的格式,而JSONP則是一種非官方跨域數(shù)據(jù)交互協(xié)議。
首先來說一下前端JS是怎么發(fā)送請求。代碼如下所示:
$.ajax({
url:"your url",
type:"get or post",
async:false,
dataType : "jsonp",
//服務端用于接收callback調(diào)用的function名的參數(shù)
jsonp:"callbackparam",
//callback的function名稱
jsonpCallback:"success_jsonpCallback",
success:function(data){
console.log(data);
},
error:function(data){
console.log(data);
}
});
這里的callbackparam和success_jsonpCallback可以理解為發(fā)送的data數(shù)據(jù)的鍵值對,可以自定義,但是callbackparam需要和后臺約定好參數(shù)名稱,因為后臺需要獲取到這個參數(shù)里面的值(即success_jsonpCallback)。
下面,最重要的來了,后臺怎么樣獲取和返回數(shù)據(jù)呢。代碼如下所示:
PrintWriter out =null;
String callback=req.getParameter("callbackparam");
String json=callback+"({'status':'ok'})";
try
{
out = resp.getWriter();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
out.print(json);
out.flush();
out.close();
首先需要獲取參數(shù)名為callbackparam的值,這里獲取到的值就是“success_jsonpCallback”。然后將這個值加上一對小括號。小括號里放入你需要返回的數(shù)據(jù)內(nèi)容,比如這里我返回一個JSON對象。當然你也可以返回其他對象,比如只返回一個字符串類型數(shù)據(jù)也可以。最后前端JS返回的數(shù)據(jù)就是這樣的:
success_jsonpCallback({'status':'ok'})
瀏覽器會自動解析為json對象,這時候你只需要在success回調(diào)函數(shù)中直接用data.status就可以了。
跨域問題一般都在后臺程序解決,將自己的程序通過配置文件或者代碼將其允許跨域,
在有跨域安全的時候,所有前端post請求時,會發(fā)送一個與其請求名字一樣的OPTIONS
此請求沒有任何參數(shù),此機制為post不知道是否有權(quán)限請求接口,發(fā)送了一個探知請求,探知
請求確認后,允許訪問后調(diào)用正常Post接口。 不允許就會出現(xiàn)你現(xiàn)在的問題跨域異常。
萌新,java是開源的,比NET好多了,多看看底層
場景:前后端分離,頁面和后端項目部署在不同服務器,出現(xiàn)請求跨域問題。
原因:CORS:跨來源資源共享(CORS)是一份瀏覽器技術(shù)的規(guī)范,提供了 Web 服務從不同網(wǎng)域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,是 JSONP 模式的現(xiàn)代版。與 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。用 CORS 可以讓網(wǎng)頁設計師用一般的 XMLHttpRequest,這種方式的錯誤處理比JSONP要來的好,JSONP對于 RESTful 的 API 來說,發(fā)送 POST/PUT/DELET 請求將成為問題,不利于接口的統(tǒng)一。但另一方面,JSONP 可以在不支持 CORS 的老舊瀏覽器上運作。不過現(xiàn)代的瀏覽器(IE10以上)基本都支持 CORS。
預檢請求(option):在 CORS 中,可以使用 OPTIONS 方法發(fā)起一個預檢請求(一般都是瀏覽檢測到請求跨域時,會自動發(fā)起),以檢測實際請求是否可以被服務器所接受。預檢請求報文中的 Access-Control-Request-Method 首部字段告知服務器實際請求所使用的 HTTP 方法;Access-Control-Request-Headers 首部字段告知服務器實際請求所攜帶的自定義首部字段。服務器基于從預檢請求獲得的信息來判斷,是否接受接下來的實際請求。
解決方案:
1、創(chuàng)建一個過濾器,過濾options請求。
package com.biz.eisp.sci.util;
import org.apache.commons.httpclient.HttpStatus;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 解決跨域問題
*?
*/
public class CorsFilterimplements Filter {//filter 接口的自定義實現(xiàn)
public void init(FilterConfig filterConfig)throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
? ? HttpServletRequest request = (HttpServletRequest) servletRequest;
? ? response.setHeader("Access-Control-Allow-Origin", "*");
? ? if ("OPTIONS".equals(request.getMethod())){//這里通過判斷請求的方法,判斷此次是否是預檢請求,如果是,立即返回一個204狀態(tài)嗎,標示,允許跨域;預檢后,正式請求,這個方法參數(shù)就是我們設置的post了
? ? ? ? response.setStatus(HttpStatus.SC_NO_CONTENT); //HttpStatus.SC_NO_CONTENT = 204
? ? ? ? response.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, OPTIONS, DELETE");//當判定為預檢請求后,設定允許請求的方法
? ? ? ? response.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with"); //當判定為預檢請求后,設定允許請求的頭部類型
? ? ? ? response.addHeader("Access-Control-Max-Age", "1");? // 預檢有效保持時間
? ? }
filterChain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
2、修改web.xml文件
filter
filter-namecors/filter-name
filter-classcom.biz.eisp.sci.util.CorsFilter/filter-class
/filter
filter-mapping
filter-namecors/filter-name
url-pattern/*?/url-pattern
/filter-mapping
3、spring-mvc.xml添加HttpRequestHandlerAdapter?http請求處理器適配器。
HttpRequestHandlerAdapter作為HTTP請求處理器適配器僅僅支持對HTTP請求處理器的適配。它簡單的將HTTP請求對象和響應對象傳遞給HTTP請求處理器的實現(xiàn),它并不需要返回值。它主要應用在基于HTTP的遠程調(diào)用的實現(xiàn)上。
bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/