JS跨域两三事

 

今日,前端开发要求新的Web服务需要支持跨域,因为要发起 Ajax 到后端web 服务域名请求数据;

 

前端application域名是 other.abc.com (举个栗子)  api接口域名是 another.abc.com。

 

后端web application是SpringMVC开发,于是,我在web.xml 配置了新Filter。

Filter代码是这样:

 1 public class CrossDomainFilter implements Filter {
 2 
 3     private static final Logger logger = LoggerFactory.getLogger(CrossDomainFilter.class);
 4 
 5     @Override
 6     public void init(FilterConfig filterConfig) throws ServletException {
 7 
 8     }
 9 
10     @Override
11     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
12         HttpServletRequest req = (HttpServletRequest) request;
13 
14       
15         String originDomain = req.getHeader("origin");  
16 
17         String[] hostSplit = StringUtils.split(originDomain, ".");
18         String subDomain = null != hostSplit && hostSplit.length >= 2 ? hostSplit[hostSplit.length - 2] + "." + hostSplit[hostSplit.length - 1] : null;
19 
20         if (StringUtils.isNotEmpty(originDomain) && StringUtils.isNotEmpty(subDomain) && subDomain.equals("abc.com")) {
21             // 允许js 跨域
22             HttpServletResponse res = (HttpServletResponse) response;
23             res.setHeader("Access-Control-Allow-Origin", originDomain);
24             res.setHeader("Access-Control-Allow-Credentials", "true");
25             res.setHeader("Access-Control-Allow-Methods", "*");
26             res.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
27         }
28         chain.doFilter(request, response);
29 
30     }
31 
32     @Override
33     public void destroy() {
34 
35     }
36 }

 

开发完成后我本地写一个简单的页面做测试,是一个php编写的Web页面,一开始是这样的:

 1 <html>
 2     
 3     <head>
 4         <title>前端页面 - js跨域local测试</title>
 5         <script src="https://cdn.bootcss.com/jquery/3.2.1/core.js"></script>
 6     </head>
 7 
 8     <body>
 9 
10         <a href="javascript:;" class="do_request">请求</a>
11 
12         <script type="text/javascript">
13             $(function () {
14                 $(".do_request").on("click", function () {
15                     console.log("request sent!");
16 
17                     $.ajax({
18                 
19                       url: "http://another.abc.com:8080/geo/gpsconvert",
20                       data: {
21                           "_gps":"120,30"
22                       },
23 
24                       success: function (res) {
25                           alert(res.succ);
26                       },
27                       dataType: "jsonp"
28                     });
29                                         
30                 });
31             });
32         </script>
33     </body>
34 </html>

 

本地点击发 Ajax 请求给后端接口,发现 req.getHeader("origin")  这个返回总是 null,百思不得其解,

经过前端提示得知,发送ajax 请求必须按照下面:

 1 $.ajax({
 2   crossDomain: true,
 3   url: "http://another.abc.com:8080/geo/gpsconvert",
 4   data: {
 5       "_gps":"120,30"
 6   },
 7 
 8   success: function (res) {
 9         alert(res.succ);
10       
11   },
12   dataType: "json"
13 });

 

服务端的 origin 才能拿到 请求发起方的host,jsonp 不是真正的CORS!而是一种跨域trick,另外

jsonp 只支持GET!

 

设置  crossDomain: true  后,服务端 origin 正常。

对PHP 来说,只要一行代码:  

  $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : null;

 

此外,Access-Control-Allow-Origin 的值谁请求上来给谁设置Response Header 即可。不建议设置 为 Access-Control-Allow-Origin: *

这样相当于所有请求的域都允许跨域了,显然不大合适。

 

posted @ 2017-12-13 20:03  Joynic  阅读(219)  评论(0编辑  收藏  举报