即使启用了 CORS,POST 也会被阻止

Posted

技术标签:

【中文标题】即使启用了 CORS,POST 也会被阻止【英文标题】:POST Blocked even when CORS is enabled 【发布时间】:2015-05-05 11:38:38 【问题描述】:

我根据 SpringMVC 指南创建了一个 SimpleCORSFilter 以允许 CORS:

@Component
public class SimpleCORSFilter implements Filter 

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-by");
        chain.doFilter(req, res);
    

POST 和 PUT 请求的控制器代码如下:

@RequestMapping(
        produces = MediaType.APPLICATION_JSON_VALUE,
        method = RequestMethod.PUT,
        value = "admin/tile/id"
)
public boolean saveNewTile(@PathVariable("id") String id) 
    ContextEntity contextEntity = new ContextEntity("tile", id);
    //TODO: USE CUSTOM DATABASE
    contextEntityDAO.save(contextEntity);

    return true;


@RequestMapping(
        produces = MediaType.APPLICATION_JSON_VALUE,
        method = RequestMethod.POST,
        value = "admin/tile/id"
)
public boolean updateTile(@PathVariable("id") String id, @RequestParam(required = false) ContextAttribute[] atts) 
    ContextEntity contextEntity = contextEntityDAO.findById(id);
    contextEntity.addContextAttributes(atts);

    contextEntityDAO.save(contextEntity);
    return true;

使用 AngularJS v1.3.14 我可以执行 GET 和 PUT 请求,但是当我尝试执行 POST 时,Firefox 会通知我该请求已被阻止,因为同源策略...

这部分工作正常,例如

$scope.onTestOnlyClick = function() 
  $http.put('http://localhost:8080/admin/tile/' + tile.id)
;

但是,当我这样做时

$http.post('http://localhost:8080/admin/tile/' + tile.id, contextAtts);

无法完成请求,两行在同一个控制器中!

这是我在 Firebug 中看到的,由于某种原因,当我执行 POST 时,Firebug 只显示一个 OPTIONS 请求,之后没有 POST。

谢谢。

【问题讨论】:

可以添加控制器代码吗? 您能否在发送实际请求之前检查您的请求是否执行了 OPTIONS 请求?根据规范:“用户代理使用 OPTIONS 方法执行预检请求”w3.org/TR/cors @sgpalit 马上! ;) @OnurAktaş 我该如何检查? 您是否尝试过发布到不同的 URL '/tile2/id 【参考方案1】:

在您的过滤器中将 Content-Type 添加到 Access-Control-Allow-Headers。在我的本地测试成功。

response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Origin, Cache-Control, X-Requested-With");
    response.setHeader("Access-Control-Allow-Credentials", "true");

【讨论】:

像魅力一样工作!您能否在回答中解释这些变化背后的理论?【参考方案2】:

尝试这样做-

@Component
public class SimpleCORSFilter implements Filter 

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-by");
        chain.doFilter(req, res);
        return;
     

【讨论】:

以上是关于即使启用了 CORS,POST 也会被阻止的主要内容,如果未能解决你的问题,请参考以下文章

跨域请求被阻止:即使在我的 API 上启用了 CORS 后也会发生;

Ajax POST 到 Laravel API 偶尔会被 CORS 阻止

即使标题正确,POST 调用也会返回 CORS 错误

XAMPP:即使我更改了 MySQL 端口,它也会被阻止

[AWS-S3] POST 上的预签名 URL 被 CORS 阻止,尽管 CORS 配置启用它

即使由用户事件触发,Facebook 权限弹出窗口也会被阻止。为啥?