如何解决请求资源中缺少'Access-Control-Allow-Origin'头的问题
解决AJAX跨域的CORS错误:缺少Access-Control-Allow-Origin头
嘿,这个问题我太熟悉了!我之前在调用跨域REST接口的时候也碰到过一模一样的报错,本质就是浏览器的同源策略在搞事情——你的前端页面跑在http://localhost:8080,但请求的REST服务在另一个域名/端口,浏览器会默认拦截这种跨域请求,除非服务端明确告诉浏览器“允许这个来源访问我”。
先明确你遇到的错误:
请求的资源上不存在'Access-Control-Allow-Origin'头,因此来源'http://localhost:8080'被拒绝访问。
下面给你几个在Java Web环境(因为你用了JSP)里亲测有效的解决方案:
方案1:在单个接口/请求里直接添加响应头
如果你的REST服务是用Servlet或者JSP实现的,可以在处理请求的代码里直接设置CORS响应头:
// 获取HttpServletResponse对象 response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080"); // 如果你需要允许所有来源(开发环境可以临时用,生产环境绝对不要!) // response.setHeader("Access-Control-Allow-Origin", "*"); // 如果需要携带Cookie或者自定义请求头,还要加这几个头 response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
方案2:用过滤器统一处理所有请求的CORS
如果有多个接口要处理跨域,写一个全局过滤器更高效,不用每个接口都重复加代码:
首先创建一个过滤器类:
import javax.servlet.*; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CORSFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; // 允许你的前端来源 response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080"); // 允许携带Cookie response.setHeader("Access-Control-Allow-Credentials", "true"); // 允许的请求方法 response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); // 允许的请求头 response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); chain.doFilter(req, res); } @Override public void init(FilterConfig filterConfig) {} @Override public void destroy() {} }
然后在web.xml里配置这个过滤器,让它对所有请求生效:
<filter> <filter-name>CORSFilter</filter-name> <filter-class>com.your.package.CORSFilter</filter-class> </filter> <filter-mapping> <filter-name>CORSFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
方案3:如果用Spring框架(Spring Boot/Spring MVC)
如果你的REST服务是基于Spring的,那就更简单了,可以用注解或者全局配置:
单个接口/控制器添加跨域支持
@RestController // 允许指定来源访问这个控制器下的所有接口 @CrossOrigin(origins = "http://localhost:8080") public class YourRestController { // 你的接口方法 @GetMapping("/api/data") public String getData() { return "Hello from cross-domain API!"; } }
全局跨域配置
@Configuration public class WebCorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 对所有路径生效 .allowedOrigins("http://localhost:8080") // 允许的来源 .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的请求方法 .allowCredentials(true); // 允许携带Cookie } }
额外提醒:处理预检请求(OPTIONS)
浏览器在发送一些“复杂请求”(比如带自定义头、POST非表单格式的数据)之前,会先发送一个OPTIONS请求来检查权限,所以要确保你的服务端能正确响应OPTIONS请求——上面的方案都已经处理了这个问题,不用额外操作。
最后再啰嗦一句:生产环境千万不要用*允许所有来源,一定要指定具体的业务域名,避免安全风险!
内容的提问来源于stack exchange,提问作者Sudarsan San
相关产品推荐
相关产品推荐

