java开发前端开发

Jfinal前后端分离项目CORS问题处理

2020-03-04  本文已影响0人  CrazyAirhead

概要

对于前后端分离的项目,无论是开发还是部署,可能都会碰到CORS问题。采用Jfinal-undertow方式发布的应用来说,通常是不需要考虑CORS的,因为前端与后端是一起发布的,但在开发时或采用分离部署时,还是会碰到的这个问题,因此在这里按开发和部署两部分讲解如何解决CORS问题。

首先我们简单的了解下什么是CORS,完整的资料可以自己查看wikipedia

CORS

跨域资源共享(CORS,Cross-origin resource sharing),它是一种允许受限的访问第一个访问资源域以外的资源(如字体)的机制。一张网页通常包含了很多跨域的图片,样式,脚本,iframes,或者视频,但一些跨域请求,尤其是Ajax请求,会因为默认的同源安全策略(简单来说就是绝对路径,需要是协议,域名,端口号三者与第一个访问的资源(浏览器中输入的URL)相同,才被认为是同源)而被禁止访问。

CORS定义了浏览器和服务器如何来决定一个跨域请求是安全的。它比完全同源请求有更多的自由和功能,但不要只是简单地允许所有跨源请求。CORS规范最初是作为W3C推荐标准发布的,但该文档已经过时。 Fetch Living Standard是当前维护活跃的规范。

对于程序开发来说,可能知道与CORS相关的请求头与响应头,已经够用了。如果需要更细的控制,可以进一步的阅读文档。

请求头

响应头

我们通常使用的是Access-Control-Allow-Origin: *

开发阶段

前端处理

如果后端没有做任何处理的情况,前端通常使用设置Chrome跨域选项和配置vue-cli代理模式这两种方式。推荐使用配置vue-cli代理模式,因为测试人员就可以不需要修改选项了。

修改Chrome跨域选项

对于Windows用户来说,创建个Chrome的快捷方式,target后中增加--disable-web-security --user-data-dir=即可,如:

"...\chrome.exe" --disable-web-security --user-data-dir=

对于MacOS用户来说,需要创建好用户数据目录,否则可能无法打开。

open -n /Applications/Google\ Chrome.app/ --args --disable-web-security --user-data-dir=/Users/work/ChromeDevUserData

vue-cli修改代理模式

参照vue-cli3的文档中的devServer.proxy配置即可。

module.exports = {
  /**
   * vue-cli3跨域的全配置!
   */
  devServer: {
     proxy:  'http://172.26.0.252:8881'
  }
}

后端处理

当然我们是希望前端不需要做任何配置,此时后端需要做些开发。实现的方式有很多,这里只展示一种方式简单的实现方式,通过扩展Interceptor实现CorsInterceptor,代码如下:

public class CorsInterceptor implements Interceptor {
  @Override
  public void intercept(Invocation inv) {
    inv.invoke();
    addCorsHead(inv.getController().getResponse());
  }

  private void addCorsHead(HttpServletResponse response) {
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader(
        "Access-Control-Allow-Headers",
        "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
  }
}

//针对性的提供Cors支持
@Before(CorsInterceptor.class)
public class IndexController extends Controller {
  public void index() {
    renderJson(Ret.ok());
  }
}

public class DemoConfig extends JFinalConfig {
  @Override
  @Override
  public void configInterceptor(Interceptors me) {
    //此处可以加个参数判断,是否加载CorsInterceptor
    me.addGlobalActionInterceptor(new CorsInterceptor());
  }
} 

部署阶段

Jfinal-undertow部署目录结构

jfinal-undertow推荐采用目录结构部署系统,当然也支持fatjar打包,可以参看jfinal-undertow 下部署。以下是就打包好后的目录格式。

.app
├──config
├──lib
├──webapp
|  └──index.html
└──jfinal.sh

采用这种方式部署是没有跨域问题的。

Nginx部署

正式环境更多的可能会用Nginx来做反向代理,将不同域名整一起。以下是简单示例,仅供参考:

server {
  listen 80;
  server_name demo.com;
  client_max_body_size 50m;

  location / {
    proxy_pass http://172.17.0.1:80;
  }

  location /api {
    proxy_pass http://172.17.0.1:81/api;
  }
}

参考链接

CORS 跨域资源共享

上一篇下一篇

猜你喜欢

热点阅读