在web开发中我们经常会说起脚本的跨域访问的问题,会出现跨域访问的限制是因为javascript语言安全限制中的同源策略(same-origin policy )所造成的。
同源策略简单的说就是一段脚本只能读取来自于同一来源的资源,这里的同一来源指的是主机名、协议和端口号的组合;举个例子具体说明
我们的主机地址http://localhost:8080/test/b.html的js脚本访问下列url的结果和原因
URL 结果 原因
http://localhost:8080/tset/d.html 成功
https://localhost:8080/tset/c.html 失败 协议不同
http://localhost:8080/tset/c.html 失败 端口不同
http://www.sina.com.cn/a/b.html 失败 主机名不同
所有只有当访问的url中,协议,主机名,端口号一致是才被视为同一来源,其他情况则一般为跨域请求。
出现了跨域请求我们已经如何解决呢?
首先说ajax中的jsonp实现跨域请求,在学习jsonp跨域请求前建议看一下jsonp的实现原理,http://kb.cnblogs.com/page/139725/页面代码
$.ajax({
type: "GET", //jsonp跨域请求只能是get请求
async: true, //jsonp跨域请求只能是异步请求
contentType:'application/x-javascript;charset=utf-8',
url: 'http://localhsot:8080/jee/sys2/getth/path',
data:{xpath:xpath,href:href,title:title},
dataType: "jsonp",
jsonp:"callback",//用以获取回调函数的参数名
jsonpCallback:"jsonpCallback", //定义回调函数名称
success: function(data){ //定义了回调函数名称ajax自己处理返回的数据,传回success属性中
alert(data.tishi);
},error:function(){}
});
后台代码
String callback=request.getParameter("callback"); //通过参数获取到客户端的回调函数
String data=callback+"({\"tishi\":\"保存成功!\"})"; //拼成回调函数加json的格式
response.setHeader("Content-type", "application/x-javascript;charset=utf-8");
response.getWriter().write(data);
由于浏览器内核等限制,有事并不支持ajax的请求,所以不能使用ajax请求时我们可以使用javascript 原生的xmlhttprequest实现跨域的请求
var postpath = "path=123";
var xmlhttp = new XMLHttpRequest();
//xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 这是老版ie使用的创建xhttprequest对象的方法
var URL = "http://localhsot:8080/jee/sys2/getath/path";
xmlhttp.open("POST", URL, true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send(postpath);
xmlhttp.onreadystatechange = function() {
if ((xmlhttp.readyState == 4) && (xmlhttp.status == 200)) {
var b = xmlhttp.responseText;
else {
}
}
在js原声的跨域请求中,后台的代码中一定要设置response的head中包含(Access-Control-Allow-Origin”, “*”),Access-Control-Allow-Origin的意思为允许访问的请求来源,后面的*表示允许一切请求访问
后台代码示例
String path=request.getParameter("path");
response.setHeader("Content-type", "application/x-javascript;charset=utf-8");
response.setHeader("Access-Control-Allow-Origin", "*");
response.getWriter().write(data);
这样使用xhttprequest的一次跨域的请求就完成了