实测 CORS 跨域访问之 Access-Control-Allow-Origin 多域名设置

  • Post author:
  • Post category:其他

初学,表述不规范之处还望不吝赐教。

1、基本思路

  在 Windows 主机与 Linux 虚拟机上同时启动 tomcat 服务器,分别模拟跨域的客户端和服务器端。当客户端(Windows)通过页面 ajax 请求服务器端(Linux)的数据时,如果请求头的 Origin 与响应头的 Access-Control-Allow-Origin 匹配成功,则传回 JSON 格式的请求数据;如果允许多个域名访问,则让 Origin 与一个域名数组(白名单)进行逐一比较,匹配成功则显示相应数据。 

 2、域名准备 

(1)客户端域名:http://www.corsdemo.com:8080(即 127.0.0.1) 

(2)服务器域名:http://192.168.92.88:8080 

(3)实测任务描述:让客户端用两种域名(http://www.corsdemo.com:8080/ 和 http://localhost:8080/)实现 CORS 跨域访问服务器,并显示所需数据结果。

3、客户端准备 

Windows:%CATALINA_HOME%\webapps\ROOT\DemoCORS.html

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CORS Demo</title>
<script
src="http://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script>
$(function(){
	$("#msg").click(function(){
		$.post("http://192.168.92.88:8080/DemoCORS/CorsServlet",function(data){
			alert(data);
			$("#msg").html("My name is " + data.name + ", at age of " + data.age + "," + 
					(data.isEngineer ? " an engineer" : "") + " from " + data.company);
		},"json");
	});
});
</script>
</head>
<body>
<h1>CORS Demo</h1>
<h2 id="msg">单击实现 CORS 跨域访问</h2>
</body>

4、服务器端准备 

(1)Servlet:(Linux)%CATALINA_HOME%/DemoCORS/WEB-INF/classes/action/CorsServlet.java  

@WebServlet("/CorsServlet")
public class CorsServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public CorsServlet() { super(); }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	String[] whiteList = {"http://www.corsdemo.com:8080", "http://localhost:8080"};
    	String myOrigin = request.getHeader("origin");
    	boolean isValid = false;
    	for( String ip : whiteList ) {
    		if( myOrigin != null && myOrigin.equals(ip) ){
    			isValid = true;
    			break;
    		}
    	}
    	response.setHeader("Access-Control-Allow-Origin", isValid ? myOrigin : "null");
    	
    	User user = new User("Andy", 28, "Google", true);
    	String data = new Gson().toJson(user);
    	response.setCharacterEncoding("UTF-8");
    	response.getWriter().print(data);
    }

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

}

(2)请求数据:(Linux)%CATALINA_HOME%/DemoCORS/WEB-INF/classes/entity/User.java

public class User {
	private String name;
	private int age;
	private String company;
	private boolean isEngineer;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getCompany() {
		return company;
	}
	public void setCompany(String company) {
		this.company = company;
	}
	public boolean isEngineer() {
		return isEngineer;
	}
	public void setEngineer(boolean isEngineer) {
		this.isEngineer = isEngineer;
	}
	public User(){}
	public User(String name, int age, String company, boolean isEngineer){
		this.name    	= name;
		this.age     	= age;
		this.company 	= company;
		this.isEngineer = isEngineer;
	}
}

5、运行结果

(1)通过 http://localhost:8080/打开:






(2)通过 http://www.corsdemo.com:8080/ 打开:





结论

客户端通过 http://www.corsdemo.com:8080/DemoCORS.html 或 http://localhost:8080/DemoCORS.html 均可以实现 CORS 跨域访问。

注意事项

1、Access-Control-Allow-Origin 不支持连续设置以逗号分隔的多个域名,如:”domain1.com,domain2.com”;

2、请求头的 Origin 由浏览器自动指定,不可手动更改,但可以通过 request.getHeader(“origin”) 读取该值;

3、站点外打开网页文件,请求头的 Origin 为 null。例如在本地磁盘任意位置直接双击打开 DemoCORS.html,url 显示为:file:///E:/Java/DemoCORS.html,单击后 Origin 为 null,本例对这种情况也允许访问,因此可以正常显示数据。否则控制台会提示同源策略限制:




版权声明:本文为frgod原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。