【发布时间】:2013-04-24 03:39:07
【问题描述】:
我有一个由 Tomcat 托管的静态网站。
如何为我的网站设置标题,例如:Access-Control-Allow-Origin: *
它们都是静态文件,不是任何 servlet 应用程序。
【问题讨论】:
-
这能回答你的问题吗? Access-Control-Allow-Origin: * in tomcat
标签: tomcat
我有一个由 Tomcat 托管的静态网站。
如何为我的网站设置标题,例如:Access-Control-Allow-Origin: *
它们都是静态文件,不是任何 servlet 应用程序。
【问题讨论】:
标签: tomcat
您需要添加一个Filter 来添加额外的标头并将其配置到所有路径
<filter>
<filter-name>header</filter-name>
<filter-class>...</filter-class>
</filter>
<filter-mapping>
<filter-name>header</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
【讨论】:
Servlet 或 Filter 在 Tomcat 中,您将无法添加标头
这是一个非常基本的过滤器,它将添加 CORS 标头。请注意,默认情况下,这将启用所有域和方法,因此您应该对其进行自定义以满足您的需求。
它还需要是 web.xml 中的第一个过滤器。
package com.conductiv.api.listener;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CORSFilter implements Filter {
public void destroy() {
}
public static String VALID_METHODS = "DELETE, HEAD, GET, OPTIONS, POST, PUT";
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpResp = (HttpServletResponse) resp;
// No Origin header present means this is not a cross-domain request
String origin = httpReq.getHeader("Origin");
if (origin == null) {
// Return standard response if OPTIONS request w/o Origin header
if ("OPTIONS".equalsIgnoreCase(httpReq.getMethod())) {
httpResp.setHeader("Allow", VALID_METHODS);
httpResp.setStatus(200);
return;
}
} else {
// This is a cross-domain request, add headers allowing access
httpResp.setHeader("Access-Control-Allow-Origin", origin);
httpResp.setHeader("Access-Control-Allow-Methods", VALID_METHODS);
String headers = httpReq.getHeader("Access-Control-Request-Headers");
if (headers != null)
httpResp.setHeader("Access-Control-Allow-Headers", headers);
// Allow caching cross-domain permission
httpResp.setHeader("Access-Control-Max-Age", "3600");
}
// Pass request down the chain, except for OPTIONS
if (!"OPTIONS".equalsIgnoreCase(httpReq.getMethod())) {
chain.doFilter(req, resp);
}
}
public void init(FilterConfig config) throws ServletException {
}
}
【讨论】:
如果是静态站点,那么从 Tomcat 7.0.41 开始,您可以通过内置过滤器轻松控制 CORS 行为。
参考资料:
您几乎唯一需要做的就是在CATALINA_HOME/conf 中编辑全局web.xml 并添加过滤器定义:
但请注意,Firefox 不喜欢 Access-Control-Allow-Origin: * 和带有凭据 (cookie) 的请求:when responding to a credentialed request, server must specify a domain, and cannot use wild carding.
如果您想在这种情况下调试请求,请注意,根据此流程图,只有在存在跨域请求时才会发送 CORS 标头。
(tomcat.apache.org/tomcat-8.0-doc/images/cors-flowchart.png)
【讨论】:
<filter> <filter-name>CorsFilter</filter-name> <filter-class>org.apache.catalina.filters.CorsFilter</filter-class> <init-param> <param-name>cors.allowed.origins</param-name> <param-value>*</param-value> </init-param> </filter>
请注意,要使用值 * 配置 CORS 过滤器,除了启用文件管理器之外,您还需要为参数 <param-name>cors.allowed.origins</param-name> 添加配置,如下所示(基于 Johannes Jander @987654321 @):
<!-- ================== Built In Filter Definitions ===================== -->
...
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- ==================== Built In Filter Mappings ====================== -->
【讨论】: