JavaScript跨域

JavaScript 跨域

出自:https://www.cnblogs.com/best/p/6196202.html

一、请求路径组成

协议://+[用户名/密码@]+主机+公司名+机构名+:端口+/路径

二、域名

主机+公司名+机构名

三、域

协议://+主机+公司名+机构名+:端口

四、什么是跨域

因为JavaScript同源策略的限制,A域名下的JavaScript无法操作B或是C域名下的对象,所以就出现跨域一词;

同源策略:

请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同。

所以跨域就是: 域名,端口,协议三者其一不同;

五、实现跨域

5.1、JSONP跨域

5.1.1、javaScript实现JSONP跨域

JSONP跨域是利用script脚本允许引用不同域下的js实现的,将回调方法带入服务器,返回结果时回调。

@WebServlet(name = "JSONPServlet", urlPatterns = "/callback")
public class JSONPServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String callback =  request.getParameter("callback");
        System.out.println(callback);
        response.getWriter().write(callback+"('"+new Date().toLocaleString()+"')");
    }
}
服务器
<body>
        <h1>JSONP跨域</h1>
        <h2>JSONP跨域是利用script脚本允许引用不同域下的js实现的,将回调方法带入服务器,返回结果时回调。</h2>
        <script type="text/javascript" src="js/jquery-1.11.3.js" ></script>
        <script type="text/javascript">
            var show = function ( data){
                window.alert(data);
            }
        </script>
        <script type="text/javascript" src="http://localhost:8080/callback?callback=show" charset="utf-8"></script>
    </body>
客户端

结果:

     服务器返回一段javascript,通过指定的方法名调用。从图中可以看出,使用JSONP的形式调用已经不再是通过XMLHTTPRequest对象,而是同步调用。

5.1.2、jQuery使用JSONP跨域
@WebServlet(name = "JSONPServlet", urlPatterns = "/callback")
public class JSONPServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String callback =  request.getParameter("callback");
        System.out.println(callback);
        response.getWriter().write(callback+"('"+new Date().toLocaleString()+"')");
    }
}
服务器
<script type="text/javascript" src="js/jquery-1.11.3.js" ></script>
        <script type="text/javascript">
            $("#cross_domain--button").click( function (){
                $.get("http://localhost:8080/callback?callback=?",function(data){
                    alert(data)
                }, "jsonp")
            });
        </script>
客户端

 

在jQuery中如果使用JSONP只需要将返回数据类型设置为jsonp就可以了。

总结:

1、只支持get请求,不支持post请求;

2、请求是同步的;服务器返回数据要处理,要添加回调函数。

5.2、跨域资源共享(cors)

同源策略(same origin policy)的限制下非同源的网站之间不能发送 ajax 请求的。

w3c 提出了跨源资源共享CORS即Cross Origin Resource Sharing(跨域源资源共享),就是我们所熟知的跨域请求。

跨域资源共享(CORS)是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源。

CORS与JSONP相比:

1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。

2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。

3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS。

4、CORS 将请求分为两类:简单请求和非简单请求:

5.2.1、简单请求
/**
 * 实现CORS简单跨域服务
 */
@WebServlet(name = "SimpleServlet", urlPatterns = "/simple")
public class SimpleServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置允许CORS的域名,如果是所有则使用*
        response.setHeader("Access-Control-Allow-Origin","http://127.0.0.1:8020");
        response.getWriter().write("{\"name\":\"Book\"}");
    }
}
服务器
<html>
    <head>
        <meta charset="UTF-8">
        <title>实现CORS简单跨域</title>
    </head>
    <body>
        <script type="text/javascript" src="js/jquery-1.11.3.js" ></script>
        <script type="text/javascript">
            $.get("http://localhost:8080/simple", function(data) {
                console.log(data)
                $("body").text(data.name)
            },"json");
            //跨域Post请求
            $.post("http://localhost:8080/simple", function(data) {
                console.log(data.name)
            }, "json");
        </script>
    </body>
</html>
客服端

结果:

 

简单请求的部分响应头及解释如下:

Access-Control-Allow-Origin(必含)- 不可省略,否则请求按失败处理。该项控制数据的可见范围,如果希望数据对任何人都可见,可以填写"*"。

Access-Control-Allow-Credentials(可选) – 该项标志着请求当中是否包含cookies信息,只有一个可选值:true(必为小写)。如果不包含cookies,请略去该项,而不是填写false。这一项与XmlHttpRequest2对象当中的withCredentials属性应保持一致,即withCredentials为true时该项也为true;withCredentials为false时,省略该项不写。反之则导致请求失败。

Access-Control-Expose-Headers(可选) – 该项确定XmlHttpRequest2对象当中getResponseHeader()方法所能获得的额外信息。

5.2.2、复杂请求

如说你需要发送PUT、DELETE等HTTP动作,或者发送Content-Type: application/json的内容就需要使用复杂请求了。

最先发送的是一种"预请求",此时作为服务端,也需要返回"预回应"作为响应。预请求实际上是对服务端的一种权限请求,只有当预请求成功返回,实际请求才开始执行。预请求以OPTIONS形式发送,当中同样包含域,并且还包含了两项CORS特有的内容。

5.2.2.1、Servlet支持CORS

@WebServlet(name = "ComplexServlet", urlPatterns = "/complex")
public class ComplexServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //设置允许CORS的域名,如果是所有则使用*
        response.addHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8020");
        response.addHeader("Access-Control-Allow-Methods", "GET,HEAD,POST,TRACE,OPTIONS,PUT,DELETE");
        response.addHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept");
        response.addHeader("Access-Control-Allow-Credentials", "true");
        response.getWriter().write("{\"name\":\"Book\"}");
    }

    @Override
    protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
服务器
<html>
    <head>
        <meta charset="UTF-8">
        <title>实现CORS复杂跨域</title>
    </head>
    <body>
        <script type="text/javascript" src="js/jquery-1.11.3.js" ></script>
        <script type="text/javascript">
            $.ajax({
                type:"post",
                url:"http://localhost:8080/complex",
                contentType:"application/json;charset=utf-8",
                dataType:"json",
                success:function(data){
                    $("body").text(data.name);
                }
            });
        </script>
    </body>
</html>
客户端

 

Access-Control-Allow-Origin(必含) – 和简单请求一样的,必须包含一个域,不能是*号

Access-Control-Allow-Methods(必含) – 这是对预请求当中Access-Control-Request-Method的回复,这一回复将是一个以逗号分隔的列表。尽管客户端或许只请求某一方法,但服务端仍然可以返回所有允许的方法,以便客户端将其缓存。

Access-Control-Allow-Headers(当预请求中包含Access-Control-Request-Headers时必须包含) – 这是对预请求当中Access-Control-Request-Headers的回复,和上面一样是以逗号分隔的列表,可以返回所有支持的头部。

Access-Control-Allow-Credentials(可选) – 和简单请求当中作用相同。

Access-Control-Max-Age(可选) – 以秒为单位的缓存时间,允许时应当尽可能缓存。

5.2.2.2、CORSFilter
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <filter>
        <filter-name>CorsFilter</filter-name>
        <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
        <init-param>
            <param-name>cors.allowed.origins</param-name>
            <param-value>http://127.0.0.1:8020</param-value>
        </init-param>
        <init-param>
            <param-name>cors.allowed.methods</param-name>
            <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
        </init-param>
        <init-param>
            <param-name>cors.allowed.headers</param-name>
            <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
        </init-param>
        <init-param>
            <param-name>cors.exposed.headers</param-name>
            <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
        </init-param>
        <init-param>
            <param-name>cors.support.credentials</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>cors.preflight.maxage</param-name>
            <param-value>10</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CorsFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>
web.xml
@WebServlet(name = "FilterCORSServlet", urlPatterns = "/filtercors")
public class FilterCORSServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet( request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().write("{\"name\":\"Book\"}");
    }
}
服务器
<script type="text/javascript" src="js/jquery-1.11.3.js" ></script>
        <script type="text/javascript">
            $.ajax({
                type:"post",
                url:"http://localhost:8080/filtercors",
                contentType:"application/json;charset=utf-8",
                dataType:"json",
                success:function(data){
                    $("body").text(data.name);
                }
            });
        </script>
客服端

结果:

5.2.2.2、Spring MVC4.2+CORS注解

方法一、如果想对一系列接口添加 CORS 配置,可以在类上添加注解,对该类声明所有接口都有效:

@Component
@RequestMapping("/cors")
@CrossOrigin(
        origins = {"http://127.0.0.1:8020"},
        allowedHeaders = "*",
        methods = {
                RequestMethod.GET,RequestMethod.POST,RequestMethod.OPTIONS
        },
        allowCredentials = "true",
        maxAge = 90
)
public class corsController {

    //跨域 CORS--复杂请求
    @RequestMapping(value = "/cors01")
    @ResponseBody
    public String cors01() {
        return "{\"name\":\"Tom\",\"age\":999}";
    }
}
控制器
<script type="text/javascript" src="js/jquery-1.11.3.js" ></script>
        <script type="text/javascript">
            $.ajax({
                type: "POST",
                url:"http://localhost:8080/cors/cors01",
                contentType:"application/json;charset=utf-8",
                dataType:"json",
                success:function(data){
                    $("body").text(data.name);
                }
            });
        </script>
客户端

结果:

方法二、修改配置文件:

<!--跨域-->
    <mvc:cors>
        <mvc:mapping path="/cors/*"
                     allowed-origins="http://127.0.0.1:8020"
                     allowed-methods="POST,GET,OPTIONS,DELETE,PUT"
                     allowed-headers="Content-Type,ContentType,Access-Control-Allow-Headers, Authorization, X-Requested-With"
                     allow-credentials="true"/>
    </mvc:cors>
mvcXML
@Component
@RequestMapping("/cors")
public class corsController {

    //跨域 CORS--复杂请求
    @RequestMapping(value = "/cors01")
    @ResponseBody
    public String cors01() {
        return "{\"name\":\"Tom\",\"age\":999}";
    }
}
控制器
<body>
        <script type="text/javascript" src="js/jquery-1.11.3.js" ></script>
        <script type="text/javascript">
            $.ajax({
                type: "POST",
                url:"http://localhost:8080/cors/cors01",
                contentType:"application/json;charset=utf-8",
                dataType:"json",
                success:function(data){
                    $("body").text(data.name);
                }
            });
        </script>
    </body>
客户端

转载于:https://www.cnblogs.com/zyz2018/p/9974139.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值