Skip to content

Commit

Permalink
支持 CORS
Browse files Browse the repository at this point in the history
  • Loading branch information
waylau committed Aug 22, 2015
1 parent f5b55ac commit 055bda5
Show file tree
Hide file tree
Showing 14 changed files with 797 additions and 10 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Expand Up @@ -2,5 +2,4 @@
/.idea/
/.settings/
.classpath
.project
_book
.project
112 changes: 110 additions & 2 deletions docs/Build Real-Time Web App with SSE.md
Expand Up @@ -290,7 +290,9 @@ EventSource 的用法与发布-订阅模式类似。而 send(message) 方法是

![](../images/sse-real-time-web-08.jpg)

## 错误解决
## 相关问题

### 异步请求

报如下错误:

Expand Down Expand Up @@ -365,8 +367,114 @@ EventSource 的用法与发布-订阅模式类似。而 send(message) 方法是
</servlet-mapping>
</web-app>

### 跨域请求
由于浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。

<table class="border">
<tbody>
<tr>
<th>URL</th>
<th>说明</th>
<th>是否允许通信</th>
</tr>
<tr>
<td>http://www.a.com/a.js<br>
http://www.a.com/b.js</td>
<td>同一域名下</td>
<td>允许</td>
</tr>
<tr>
<td>http://www.a.com/lab/a.js<br>
http://www.a.com/script/b.js</td>
<td>同一域名下不同文件夹</td>
<td>允许</td>
</tr>
<tr>
<td>http://www.a.com:8000/a.js<br>
http://www.a.com/b.js</td>
<td>同一域名,不同端口</td>
<td>不允许</td>
</tr>
<tr>
<td>http://www.a.com/a.js<br>
https://www.a.com/b.js</td>
<td>同一域名,不同协议</td>
<td>不允许</td>
</tr>
<tr>
<td>http://www.a.com/a.js<br>
http://70.32.92.74/b.js</td>
<td>域名和域名对应ip</td>
<td>不允许</td>
</tr>
<tr>
<td>http://www.a.com/a.js<br>
http://script.a.com/b.js</td>
<td>主域相同,子域不同</td>
<td>不允许</td>
</tr>
<tr>
<td>http://www.a.com/a.js<br>
http://a.com/b.js
</td>
<td>同一域名,不同二级域名(同上)</td>
<td>不允许(cookie这种情况下也不允许访问)</td>
</tr>
<tr>
<td>http://www.cnblogs.com/a.js<br>
http://www.a.com/b.js</td>
<td>不同域名</td>
<td>不允许</td>
</tr>
</tbody>
</table>


出于安全考虑,默认是不允许跨域访问的,会报如下异常:

![](../images/sse-real-time-web-10.jpg)

解决是服务器启动 [CORS](http://www.w3.org/TR/cors/)

先是做一个过滤器 CrossDomainFilter.java,将响应头“Access-Control-Allow-Origin”设置为“*

@Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException {
// 响应头添加了对允许访问的域,* 代表是全部域
responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");

}

在 RestApplication 里,注册该过滤器即可。

public class RestApplication extends ResourceConfig {

public RestApplication() {
// 资源类所在的包路径
packages("com.waylau.rest.resource");
// 注册 MultiPart
register(MultiPartFeature.class);
// 注册CORS过滤器
register(CrossDomainFilter.class);
}
}

这样,就能跨域访问了,如下,192.168.11.103 可以访问 192.168.11.125 站下的资源

![](../images/sse-real-time-web-11.jpg)


## 源码

`sse-real-time-web` 项目

##参考:

* Data Push Apps with HTML5 SSE(by Darren Cook)
* [Jersey 2.x 用户指南](https://github.com/waylau/Jersey-2.x-User-Guide)
* <http://www.ibm.com/developerworks/cn/web/wa-lo-comet/>
* <http://www.ibm.com/developerworks/cn/web/wa-lo-comet/>
* <https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS>
Binary file added images/sse-real-time-web-10.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/sse-real-time-web-11.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions samples/sse-real-time-web/.gitignore
Expand Up @@ -2,5 +2,4 @@
/.idea/
/.settings/
.classpath
.project
_book
.project
Expand Up @@ -3,6 +3,8 @@
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;

import com.waylau.rest.filter.CrossDomainFilter;

/**
* REST 主应用
*
Expand All @@ -12,10 +14,13 @@
public class RestApplication extends ResourceConfig {

public RestApplication() {
//资源类所在的包路径
// 资源类所在的包路径
packages("com.waylau.rest.resource");

//注册 MultiPart
// 注册 MultiPart
register(MultiPartFeature.class);

// 注册CORS过滤器
register(CrossDomainFilter.class);
}
}
@@ -0,0 +1,35 @@
package com.waylau.rest.filter;

import java.io.IOException;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;

/**
* 说明:支持 Cross-domain 请求
*
* @author <a href="http://www.waylau.com">waylau.com</a> 2015年8月22日
*/
public class CrossDomainFilter implements ContainerResponseFilter {

/**
*
*/
public CrossDomainFilter() {
// TODO Auto-generated constructor stub
}

/* (non-Javadoc)
* @see javax.ws.rs.container.ContainerResponseFilter#filter(javax.ws.rs.container.ContainerRequestContext, javax.ws.rs.container.ContainerResponseContext)
*/
@Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException {

// 响应头添加了对允许访问的域,* 代表是全部域
responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");

}

}
@@ -0,0 +1,17 @@
package com.waylau.rest.filter;

/**
* 说明:支持 Cross-domain 请求
*
* @author <a href="http://www.waylau.com">waylau.com</a> 2015年8月22日
*/
public class CrossDomainFilter2 {

/**
*
*/
public CrossDomainFilter2() {
// TODO Auto-generated constructor stub
}

}
5 changes: 5 additions & 0 deletions samples/sse-real-time-web/src/main/webapp/index.html
Expand Up @@ -9,6 +9,11 @@ <h2>Jersey RESTful Web Application!</h2>

<p>
<a href="sse_broadcast.html">进入聊天室</a>
<p>
<a href="sse_ie.html">IE 浏览器的 SSE</a>
<p>
<a href="sse_cors.html">SSE 的 CORS</a>

<h3>Get time from server</h3>
<pre id="x">Initializing...</pre>
<p>
Expand Down
@@ -0,0 +1,41 @@

/**
* Created by waylau.com on 2015/8/22
*/

//判断浏览器是否支持 EventSource
if (typeof (EventSource) !== "undefined") {
var source = new EventSource("http://192.168.11.125:8080/webapi/see-events");

// 当通往服务器的连接被打开
source.onopen = function(event) {
console.log("连接开启!");

};

// 当接收到消息。只能是事件名称是 message
source.onmessage = function(event) {
console.log(event.data);
var data = event.data;
var lastEventId = event.lastEventId;
document.getElementById("x").innerHTML += "\n" + 'lastEventId:'+lastEventId+';data:'+data;
};

//可以是任意命名的事件名称
/*
source.addEventListener('message', function(event) {
console.log(event.data);
var data = event.data;
var lastEventId = event.lastEventId;
document.getElementById("x").innerHTML += "\n" + 'lastEventId:'+lastEventId+';data:'+data;
});
*/

// 当错误发生
source.onerror = function(event) {
console.log("连接错误!");

};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events..."
}

0 comments on commit 055bda5

Please sign in to comment.