js跨域

 

一、域

  何为域? 这里说到的域指的是:协议+端口+网路域名。

  例如:在 本地的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()方法  


原文地址:https://www.cnblogs.com/getchen/p/7704732.html