文档章节

跨域之CORS

zjg23
 zjg23
发布于 2016/12/02 16:05
字数 977
阅读 520
收藏 48

实验环境准备:

本地存在一个web应用,模拟服务端。调用其接口http://127.0.0.1:8080/PanServer/files/dir/1235/query返回如下

image

客户端用一个html模拟(直接在tomcat的webapps下建一个Cors的文件夹,将html放到Cors下面),源码如下:

<html>
<head>
<meta charset="utf-8" />
<script>
function success(text) {
var textarea = document.getElementById('test-response-text');
textarea.innerHTML = text;
}

function fail(code) {
var textarea = document.getElementById('test-response-text');
textarea.innerHTML = 'Error code: ' + code;
}

function helloAjax() {
var request = new XMLHttpRequest(); // 新建XMLHttpRequest对象

request.onreadystatechange = function () { // 状态发生变化时,函数被回调
if (request.readyState === 4) { // 成功完成
    // 判断响应结果:
    if (request.status === 200) {
        // 成功,通过responseText拿到响应的文本:
		//alert('request.responseText');
        return success(request.responseText);
    } else {
        // 失败,根据响应码判断失败原因:
		//alert('request.status');
        return fail(request.status);
    }
} else {
    console.log('continuing……');
}
}

// 发送请求:
request.open('GET', 'http://localhost:8080/PanServer/files/dir/1235/query');
request.send();

alert('请求已发送,请等待响应...');
}

</script>
</head>
<body>
<div>
<p id="test-response-text"></p>
<p><button type="button" onclick="helloAjax()">刷新</button></p>
</div>
</body>
</html>

跨域测试:

1、浏览器内通过http://127.0.0.1:8080/Cors/corstest.html发起客户端调用,点击“刷新”按钮触发http://localhost:8080/PanServer/files/dir/1235/query的跨域调用

(注,localhost和127.0.0.1 作为主机名,不同,故为跨域调用),浏览器中会受到调用失败的提示

image

2、浏览器内通过http://localhost:8080/Cors/corstest.html发起客户端调用,点击“刷新”按钮触发http://localhost:8080/PanServer/files/dir/1235/query的调用

此时协议、主机名、端口均相同则不为跨域调用,可以成功返回

image

问题解决:

既然模拟出了跨域场景,接着就是用CORS的方式来让跨域调用成功。

 

tomcat下的配置
下载cors-filter-1.7.jar,java-property-utils-1.9.jar这两个库文件,放到lib目录下。(可在
http://search.maven.org上查询并下载。)服务端的工程项目中web.xml中添加如下配置: 

<filter>  
    <filter-name>CORS</filter-name>  
    <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>  
    <init-param>  
     <param-name>cors.allowOrigin</param-name>  
        <param-value>*</param-value>  
    </init-param>  
    <init-param>  
     <param-name>cors.supportedMethods</param-name>  
        <param-value>GET, POST, HEAD, PUT, DELETE</param-value>  
    </init-param>  
    <init-param>  
     <param-name>cors.supportedHeaders</param-name>  
        <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value>  
    </init-param>  
    <init-param>  
        <param-name>cors.exposedHeaders</param-name>  
        <param-value>Set-Cookie</param-value>  
    </init-param>  
    <init-param>  
        <param-name>cors.supportsCredentials</param-name>  
        <param-value>true</param-value>  
    </init-param>  
</filter>  
<filter-mapping>  
    <filter-name>CORS</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>

 

可以看到之前失败的跨域调用已经可以成功调用

image

CORS的原理:

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

以刚才成功的跨域请求为例

浏览器发现这次跨域请求是简单请求(什么是简单请求参看跨域资源共享 CORS 详解),就自动在头信息之中,添加一个Origin字段。

image

Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段,就知道出错了,从而抛出一个错误;如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段。

image

这几个字段就是我们刚才添加的fileter添加的。浏览器看到这几个头消息之后,就可以正常响应了,不会再进行拦截。上面只是简单介绍了CORS的原理,详细可以 看参考文档。

参考文档:

http://www.ruanyifeng.com/blog/2016/04/cors.html

© 著作权归作者所有

共有 人打赏支持
zjg23
粉丝 19
博文 122
码字总数 40982
作品 0
济南
程序员
私信 提问
ajax post跨域解决方案

概述 CORS能做什么: 正常使用AJAX会需要正常考虑跨域问题,所以伟大的程序员们又折腾出了一系列跨域问题的解决方案,如JSONP、flash、ifame、xhr2等等。 本文介绍的CORS就是一套AJAX跨域问题...

进击的程序员
2014/02/20
0
1
SpringBoot 实现前后端分离的跨域访问(CORS)

一、基本介绍 CORS是一种访问机制,英文全称是Cross-Origin Resource Sharing,即我们常说的跨域资源共享,通过在服务器端设置响应头,把发起跨域的原始域名添加到Access-Control-Allow-Orig...

Jokey2017
2017/11/14
0
0
AJAX POST&跨域 解决方案 - CORS

 跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是由于安全限制(同源策略, 即JavaScript或Cookie只能访问同域下的内容),因为我们在日常的项目开发时会不...

zyt_1978
2016/03/28
64
0
Tomcat 7 下 java web 项目 跨域CORS请求解决方案

首先我们先看下什么是 CORS(跨来源资源共享/跨域资源共享) 跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源。简单来说就是...

蜗牛崛起
2016/07/28
94
0
Java Web应用中支持跨域请求

由于工程合作开发的需要,后台的应用要能支持跨域访问,但是在这个跨域访问“时好时坏”,我们这帮屌丝所知道的就是加上两个jar包,然后声明一下Filter,感觉很简单的有没有!!感觉自己很牛...

lmy86263
2016/06/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Java 源代码和 C 源代码的运行区别

与其他程序的执行方式和编译方式不同。 Java 源代码需要进行编译成字节码后在 Java 虚拟机上运行,这样 Java 程序能够保持独立性和跨平台功特性。 请参考下图。 https://www.cwiki.us/pages...

honeymose
今天
4
0
Apache限定目录解析PHP,限制user_agent,PHP相关的配置

Apache限定目录解析PHP 配置前访问upload/index.php [root@test-a ~]# curl -x192.168.77.139:80 'www.test.com/upload/index.php'This is upload diretory 配置,/usr/local/apache2.4/......

野雪球
今天
5
0
java.util.Concurrent.Exchanger源码

类图 源码: package java.util.concurrent;import java.util.concurrent.atomic.AtomicInteger;import java.util.concurrent.atomic.AtomicReference;import java.util.concurrent......

狼王黄师傅
今天
6
0
Kubernetes里的secret最基本的用法

Secret解决了密码、token、密钥等敏感数据的配置问题,使用Secret可以避免把这些敏感数据以明文的形式暴露到镜像或者Pod Spec中。 Secret可以以Volume或者环境变量的方式使用。 使用如下命令...

JerryWang_SAP
昨天
5
0
2018-11-20学习笔记

1. python数据类型: 给变量赋值什么样的值,变量就是什么样的类型 给变量赋值整数,变量就是整数类型 给变量赋值字符串,变量就是字符串类型 123 和“123”一样吗? 在python中 单引号 与双...

laoba
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部