如何用CORS来解决JS中跨域的问题

JavaScript025

如何用CORS来解决JS中跨域的问题,第1张

1、CORS的原理:CORS定义一种跨域访问的机制,可以让AJAX实现跨域访问。CORS 允许一个域上的网络应用向另一个域提交跨域 AJAX 请求。实现此功能非常简单,只需由服务器发送一个响应标头即可。

2、tomcat如何配置cors的跨域请求: 

在tomcat中,有一个和cors相关的拦截器:CORS Filter

该过滤器可以通过添加必需的访问控制请求头Access-Control-*对象来进行跨域。同时还可以对一些请求进行拦截。如果请求是无效的,或者是不被允许的,该请求被拒绝或者禁止。 

其在web.xml文件中的基本配置如下:

<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://localhost:8080,

                https://localhost:8443

            </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,Access-Control-Allow-Origin

            </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>/wxrefund/*</url-pattern>

    </filter-mapping>

3、cors.allowed.origins:允许访问资源的源列表。*表示任何来源都可以访问该资源。否则,只有配置的白名单的来源可以访问该资源,其中白名单用逗号隔开,如http://localhost:8080,https://localhost:8443。

4、cors.allowed.methods:允许访问的http请求方法,如GET,POST,HEAD,OPTIONS,PUT等,方法名用逗号隔开。

5、cors.allowed.headers:在实际请求时可使用的请求头列表,用逗号隔开。如Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Access-Control-Allow-Origin。这些头也将返回作为访问控制的一部分。

AngularJS的CORS错误,解决方法是换成jsonp请求。

比如:

var url = "http://host/training_webapi?callback=JSON_CALLBACK"

$http.jsonp(url)

.success(function(data){

console.log(data.found)

})

以上利用$http.jsonp就可以避免CORS错误了,因为默认是同域名的请求,AngularJS是提供了这样的跨域方法的。

跨域资源共享( CORS )是一种机制,是W3C标准。它允许浏览器向跨源服务器,发出 XMLHttpRequest 或 Fetch 请求。并且整个 CORS 通信过程都是浏览器自动完成的,不需要用户参与。

而使用这种 跨域资源共享 的前提是,浏览器必须支持这个功能,并且服务器端也必须同意这种 "跨域" 请求。因此实现 CORS 的关键是服务器需要服务器。通常是有以下几个配置:

具体可看: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS#Preflighted_requests

过程分析:

另外在 CORS 中有 简单请求 和 非简单请求 ,简单请求是不会触发 CORS 的预检请求的,而非简单请求会。

“需预检的请求” 要求必须首先使用 OPTIONS方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

简单请求不会触发 CORS 的预检请求,若请求满足所有下述条件,则该请求可视为“简单请求”:

简单回答

详细回答

除了上面这些请求外,都是非简单请求。

若是跨域的非简单请求的话,浏览器会首先向服务器发送一个预检请求,以获知服务器是否允许该实际请求。

整个过程大概是:

这里有两点要注意:

一:

Access-Control-Request-Method 没有 s

Access-Control-Allow-Methods 有 s

二:

关于 Access-Control-Max-Age ,浏览器自身也有维护一个最大有效时间,如果该首部字段的值超过了最大有效时间,将不会生效,而是以最大有效时间为主。

还是在原本 JSONP 的那个案例上。

我在根目录下新建了一个文件夹 cors ,并往里面添加了一个 index.html 文件:

/cors/index.html

为了后面也方便调试,用 node 简单写了一个前端的本地服务和后端的本地服务。

在根目录下新建 client.js 文件,并写入:

./client.js :

在根目录下新建 index.html 文件,并写入:

./index.html :

(以上:实现了一个简单的前端路由效果)

在根目录下新建 server.js 文件,并写入:

./server.js :

并给 package.json 中配置两个启动指令:

package.json :

OK