一、域
何为域? 这里说到的域指的是:协议+端口+网路域名。
例如:在 本地的HTML文件 : file:///H:/ZLT/javascript/js%E8%B7%A8%E5%9F%9F/js%E8%B7%A8%E5%9F%9F_01.html
中请求 localhost:8080/web/a.do中的数据 就算是跨域,因为他们的网络协议就不同。
值得注意的是 即使是相同的的域名,但是对应的是不同的ip地址也算是跨域。
二、同源策略
js网络(ajax)请求,请求都是设置了同源策略的,就是通过ajax获取网络数据,默认情况下是不允许跨域请求数据的。
这是为了防止 CSRF攻击 参看博文:http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html
同源策略对应表:
三、跨域问题的解决
1)通过非同源策略的标签获取
在HTML<img> 可以请求其他网站的图片地址,这样子的标签就属于是非同源策略的标签。同样<script>标签也是非同源策略的标签
所以我们可以在本地的html文件中 这样写:
然后再通过自己的js代码,去调用非同源js文件中的方法。这种方法我们是不是在引用网络的版的jquery的时候用到过?
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script>
2) 通过ajax(jquery)获取
① 通过$.post()/$.get()方法
前端js代码
$.post("http://localhost:8080/CrossDomain/json.do",function(data){ alert(data.name); },"json");//服务器设置请求头
java后台代码
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setHeader("Access-Control-Allow-Origin", "*"); String result = "{"name":"zhangsan","date":"2017-10-20"}"; resp.setContentType("text/plusin;charset=utf-8"); resp.setCharacterEncoding("UTF-8"); resp.getWriter().write(result); }
*值得注意的是,这种求情方式必须在后端 设置允许跨域访问的响应头 :resp.setHeader("Access-Control-Allow-Origin", "*"); 其中 * 代表所有域
,亦可以自己指明允许跨域的链接
3) 通过ajax——jsonp来完成
jsonp:一种特殊的跨域的数据格式 形似json。格式为:字符(json); 例如: m({"user":"张三","age":23});
前端代码
function ajax_jsonp(){ $.ajax({ url:"http://localhost:8080/CrossDomain/json2.do", type:"GET", success:function(data){ alert(data.name); }, dataType:"jsonp", jsonpCallback:"m1", error:function(e){ alert("error"); } });
从代码中我们可以看出,跨域访问的返回数据为jsonp类型,并且比一般的ajax多了一个 jsonpCallback的字段。很多人都说,jsonCallback所携带的“m1”是一个要回调的方法
其实不是,上面提到了jsonp的数据格式,其实这个“m1”就是 jsonp格式里面的那个 字符 。也就是说服务器现在必须给你返回的数据格式,必须是 m1(json)。例如:
m1({"user":"张三","age":23}); 否则请求就是失败的。 当然你获取到数据依然是一个 json 格式的数据 ,它不包含其他多余的部分。
后端代码
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/plusin;charset=utf-8"); resp.setCharacterEncoding("UTF-8");
String result = "{"name":"zhangsan","date":"2017-10-20"}";
resp.getWriter().write("m1(" + result + ")");
}
通过后台的代码可以看出,通过jsonp跨域访问是不需要设置允许跨域的响应头的。
通过测试发现,ajax使用jsonp访问跨域资源,无论ajax的type为 post还是get,跨域访问都只访问后台的 doget()方法