跨域(CORS) 解决方案中,为什么 Access-Control-Allow-Methods 不起作用?
首先,通过阅读Mozilla的官方文档,对CORS的解决方案进行了理解。
然后,自己动手做实验来验证一下这个方案。
结果,发现当我在“Access-Control-Allow-Methods”中未设置“POST”时,页面上的POST仍然可以发送成功。无法理解,请各位赐教!
如下是我的请求截图:
按照Mozilla的官方文档上的关于“Preflighted requests”这段的描述:
第一张图应该是“预检”的请求,它的“Request Method”的确为“OPTIONS”,
而且返回的response的Header中,“Access-Control-Allow-Methods”的值为"GET,PUT,DELETE",并未包含“POST”,所以理论上POST请求应该是无法发送的才是。
但是,从第二张图来看,POST类型的请求仍然被发送了。这是怎么回事呢?想不通。
PS:我使用 Chrome、Firefox、Safari测试了,都是同样的结果。
追加
或者说,我想实现在跨域的时候,禁止客户端使用POST请求,要怎么设置才行呢?
添加测试代码
实现 CORS的filter
/**
* Servlet Filter implementation class CorsFilter
*/
@WebFilter("/*")
public class CorsFilter implements Filter {
/**
* Default constructor.
*/
public CorsFilter() {
}
/**
* @see Filter#destroy()
*/
public void destroy() {
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
String currentOrigin = request.getHeader("Origin");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET,PUT,DELETE");
response.setHeader("Access-Control-Allow-Headers", "Content-type");
// response.setHeader("Access-Control-Allow-Headers", "xxx");
chain.doFilter(req, resp);
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
}
}
测试用的 ajax
$.ajax({
"type" : "POST",
"url" : "http://ip:port/bcdae/v1/user/file/1",
"contentType" : "application/json",
"data" : JSON.stringify({
"id" : "123",
"text" : "test"
}),
"success" : function(msg){
$("#corsRes").text(msg);
}
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
火狐也是如此行为。因为标准是这么说的:
simple method 是指 GET, HEAD 或者 POST。所以这三个方法是例外的。Google 搜索时也可以观察到人们只遇到了因为这个头导致 delete 啊 put 啊 patch 啊之类的被拒绝的情况。
服务端如果不同意 POST 的话,可以不允许对应的 Origin,或者返回 403 啊什么的都可以的吧。(标准读起来好枯燥啊 :-( )
PS: 死 markdown 我明明写的「7.」,它非要给我改成「1.」,所以只好写汉字了……
第二张图状态码是 201
不太了解 chrome ,是不是会把 OPTION POST 合并显示呀?
个人感觉
Access-Control-Allow-Methods
设置的并不是服务端允许请求的方法,而是服务器支持的所有跨域请求的方法。是为了避免浏览次请求的多次'预检'请求。通过阅读Mozilla的官方文档……QAQ……
你没搞清楚Access-Control-Allow的作用啊。。。
这个是服务端返回的一个数据啊,当然是要请求了之后,才知道你的Access是不是允许的啊……
不管跨域不跨域,请求都会发出去……
请求发送了不代表JS能获取到……
区别在于浏览器是否会报错,提示你跨域了(然后获取不到数据)。
这个才是Access-Control-Allow的作用。
总之,跨域机制是阻止了数据的获取,不是阻止了请求的发送。
另外,不同浏览器不一样。
参考此文,理解下CORS:https://github.com/hstarorg/HstarDoc/blob/master/%E5%89%8D%E7%AB%AF%E7%9B%B8%E5%85%B3/CORS%E8%AF%A6%E8%A7%A3.md
另外,前面的OPTIONS请求是你POST请求发起的预请求么?