ajax 跨域请求jsonp

最近一段时间为这个事情走了不少弯路,现将成功经验分享,避免后来人再绕远路,不过也是第一次使用中间有什么问题大家可以留言探讨。

ajax的跨域请求jsonp主要运用于不同系统的交互,一个系统想通过该种方式发送一个数据,获得该数据在另一个系统的想对应数据的过程。

主要代码实现example:

        $.ajax({
		    url: url,
		    type: 'GET',
		    dataType: 'jsonp',
		    async:false,
		    jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)  
                 jsonpCallback: "jsonpcallback",//自定义的jsonp回调函数名称,注意和后台保持一致,否则会走error报textstauts:parsererror 格式错误
		    timeout : 40000,
                 success: function(data){
		        alert(data.returnFlag+"&&"+data.taskid);
		    },		
            		
		    error: function(XMLHttpRequest, textStatus, errorThrown) {
		    	 alert(XMLHttpRequest.status);
		    	 alert(XMLHttpRequest.readyState);
		    	 alert(textStatus);
		    }
		});

后台action代码:

public void receivePort(HttpServletRequest request,HttpServletResponse response) throws UnsupportedEncodingException{
		String title,taskid,creator,task_sys_sendid,task_sys_source,deptname,remark,source;
		
		String jsonpcallback = request.getParameter("callback"); // 注意与ajax保持一致
		jsonpcallback = jsonpcallback == null ? "" : jsonpcallback;  
          response.setContentType("application/x-javascript");  
             response.setCharacterEncoding("UTF-8");  
             response.setHeader("P3P", "CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR");  
		
            PrintWriter out;
		try {
			out = response.getWriter();
		     out.write("jsonpcallback({ "returnFlag":" + bln + ","taskid":"" +taskid.toString()+ ""});");  //格式注意
		        out.flush();  
		        out.close(); 
		} catch (IOException e) {
			e.printStackTrace();
		}  
      
	}

这样就可以实现跨域请求数据了。

过程错误总结:

1、报错:textstauts:parsererror →页面控制台打印Uncaught SyntaxError: Unexpected token

对比前后代码,只因为在jsonp中缺少了空格!!!此处要谨慎!

题外话:

1、XMLHttpRequest().readyState的五种状态详解 .(抄录)

(0)未初始化
此阶段确认XMLHttpRequest对象是否创建,并为调用open()方法进行未初始化作好准备。值为0表示对象已经存在,否则浏览器会报错--对象不存在。

(1)载入
此阶段对XMLHttpRequest对象进行初始化,即调用open()方法,根据参数(method,url,true)完成对象状态的设置。并调用send()方法开始向服务端发送请求。值为1表示正在向服务端发送请求。

(2)载入完成
此阶段接收服务器端的响应数据。但获得的还只是服务端响应的原始数据,并不能直接在客户端使用。值为2表示已经接收完全部响应数据。并为下一阶段对数据解析作好准备。

(3)交互
此阶段解析接收到的服务器端响应数据。即根据服务器端响应头部返回的MIME类型把数据转换成能通过responseBody、responseText或responseXML属性存取的格式,为在客户端调用作好准备。状态3表示正在解析数据。

(4)完成
此阶段确认全部数据都已经解析为客户端可用的格式,解析已经完成。值为4表示数据解析完毕,可以通过XMLHttpRequest对象的相应属性取得数据。


概而括之,整个XMLHttpRequest对象的生命周期应该包含如下阶段:
创建-初始化请求-发送请求-接收数据-解析数据-完成

在具体应用中,明确了readyState的五个状态(XMLHttpRequest对象的生命周期各个阶段)的含义,就可以消除对Ajax核心的神秘感(语焉不详的背后要么是故弄玄虚,制造神秘感;要么就是“以其昏昏,使人昭昭”),迅速把握其实质,对减少学习中的挫折感和增强自信心都极其有益。

//声明数组
var states = [“正在初始化……”,
“正在初始化请求……成功!
正在发送请求……”,
“成功!
正在接收数据……”,
“完成!
正在解析数据……”,
“完成!
”]; 

//回调函数内部代码片段
if (xmlHttp.readyState==4)
{
var span = document.createElement(“span”);
span.innerHTML = states[xmlHttp.readyState];
document.body.appendChild(span); 

if (xmlHttp.status == 200)
{
var xmldoc = xmlHttp.responseXML;
//其他代码


//别忘记销毁,防止内存泄漏
xmlHttp = null;
}else{
var span = document.createElement(“span”);
span.innerHTML = states[xmlHttp.readyState];
document.body.appendChild(span);
}结果如下:

正在初始化请求……成功!
正在发送请求……成功!
正在接收数据……完成!
正在解析数据……完成!

我们很容易明白XMLHttpRequest对象在各个阶段都在做什么。因此,也就很容易对Ajax的核心部分有一个真正简单明了的理解。

2、response.setHeader("P3P", "CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR");

但是跨域处理cookie浏览器会自动阻止此行为,不能写入cookie,也就不能读取.
网上提供的方法是在跨域请求时 设置 P3P HTTP Header 就可以完成跨域cookic的读写.
asp.net写请求的页面加入如下代码
Response.AddHeader("P3P", @"CP=""CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR""");

原文地址:https://www.cnblogs.com/ckxlovejava/p/6999675.html