请求的资源上不存在“Access-Control-Allow-Origin”标头。离子、AngularJS、Spring Boot 1.3

Posted

技术标签:

【中文标题】请求的资源上不存在“Access-Control-Allow-Origin”标头。离子、AngularJS、Spring Boot 1.3【英文标题】:No 'Access-Control-Allow-Origin' header is present on the requested resource. Ionic, AngularJS, Spring Boot 1.3 【发布时间】:2016-03-14 09:48:31 【问题描述】:

我正在使用 Ionic 和 Spring Boot 1.3。直到我升级到 1.3 才遇到这个问题...

显然在更新到 Spring Boot 1.3 之后。 CorsFilter 被完全忽略。所有这些弃用都让我发疯。所以我查找了新方法,这就是我得到的。

package app.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter 

    @Override
    public void addCorsMappings(CorsRegistry registry) 
        registry.addMapping("/**")
                .allowedOrigins("http://192.168.1.66:8101")
                .allowCredentials(false)
                .maxAge(3600)
                .allowedHeaders("Accept", "Content-Type", "Origin", "Authorization", "X-Auth-Token")
                .exposedHeaders("X-Auth-Token", "Authorization")
                .allowedMethods("POST", "GET", "DELETE", "PUT", "OPTIONS");
    

以上代码在应用程序启动时执行。与每次有请求时执行的 CorsFilter 不同。但是切换到 Spring Boot 1.3,我不能再在链过滤器中得到这个。

再次,正在加载代码,我设置了一个断点并每次调用 addCorsMapping 以便进行设置。所以....为什么我仍然收到此错误

XMLHttpRequest cannot load http://192.168.1.66:8080/login?username=billyjoe&password=happy. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://192.168.1.66:8101' is therefore not allowed access.

编辑 下面是我的旧 CorsFilter。自从我更新到 Spring Boot 1.3 后它不再工作了

package app.config;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class CorsFilter implements Filter 

    private final Logger log = LoggerFactory.getLogger(CorsFilter.class);

    public CorsFilter() 
        log.info("SimpleCORSFilter init");
    

    @Override
    public void doFilter(ServletRequest req,
                         ServletResponse res,
                         FilterChain chain) throws IOException, ServletException 

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        String clientOrigin = request.getHeader("origin");
        response.addHeader("Access-Control-Allow-Origin", clientOrigin);
        response.setHeader("Access-Control-Allow-Methods", "POST, GET,  DELETE, PUT");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Accept, Content-Type, Origin, Authorization, X-Auth-Token");
        response.addHeader("Access-Control-Expose-Headers", "X-Auth-Token");

        if (request.getMethod().equals("OPTIONS")) 
            response.setStatus(HttpServletResponse.SC_OK);
         else 
            chain.doFilter(request, response);
        
    

    @Override
    public void init(FilterConfig filterConfig) 
    

    @Override
    public void destroy() 
    


【问题讨论】:

【参考方案1】:

你可以试试这样的。它对我有用:。

@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, PUT, OPTIONS, DELETE, PATCH");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        chain.doFilter(req, res);
    

    public void init(FilterConfig filterConfig) 

    public void destroy() 


【讨论】:

感谢您的回复。在更新到 1.3 Spring Boot 之前。我有这样的东西,而且效果很好。由于我更新到 Spring Boot 1.3,它现在完全忽略了它。这就是为什么我添加了较新的设置。我在上面添加了我的 CorsFilter。它与您的相似,只是我获得了 IP 的来源并将其设置为访问控制允许来源。在任何情况下,该文件都被完全忽略,这意味着没有应用任何设置。我还想补充一点,我正在使用不允许使用 astrick 值的 WebSocket 层。【参考方案2】:

想通了。我正在使用 CustomToken 登录,出于某种原因,1.3 及更高版本的新配置在使用自定义登录身份验证时未使用 Access-Control-Allow-Origin 设置响应。所以在我的自定义登录的某个地方,我不得不添加响应头。

httpServletResponse.addHeader("Access-Control-Allow-Origin", "http://192.168.1.66:8080"); 

在旧版本的 Spring 中,CorsFilter 在过滤器中设置,因此每次调用时都会设置它。似乎新配置仅在正确调用控制器时才起作用,但由于登录是在过滤器而不是控制器中处理的,因此永远不会设置响应正文。它正确地验证了用户Access-Control-Allow-Origin

【讨论】:

【参考方案3】:

在我的一个开源项目中,在更新到 Spring 4.2 之前我需要 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, PUT, OPTIONS, DELETE, PATCH");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        chain.doFilter(req, res);
    

    public void init(FilterConfig filterConfig) 

    public void destroy() 


作为 Raca 的答案。但是,当我在 spring-boot 1.3.3 更新时,我将配置更改如下:

@SpringBootApplication
@Configuration
@EnableEurekaClient
@RibbonClients
@EnableCircuitBreaker
@EnableZuulProxy
@EnableJpaRepositories(basePackages = "it.valeriovaudi.documentlibrary.repository")
@EnableTransactionManagement
@EnableRedisHttpSession
@PropertySource("classpath:restBaseUrl.properties")
@EnableAspectJAutoProxy(proxyTargetClass = true) // without this declaration the RestTemplate injection wil be fails becouse spring cloud proxied this class for load balance with netflix ribbon
public class UserDocumentLibraryClientApplication 

    public static void main(String[] args) 
        SpringApplication.run(UserDocumentLibraryClientApplication.class, args);
    

    @Bean
    public static PropertySourcesPlaceholderConfigurer placeholderConfigurerSupport() 
        return new PropertySourcesPlaceholderConfigurer();
    

    @Bean
    public EmbeddedServletContainerCustomizer exceptionHandling() 
        return container -> container.addErrorPages(new ErrorPage("/exception"));
    

    @Bean
    public WebMvcConfigurer corsConfigurer() 
        return new WebMvcConfigurerAdapter() 
            @Override
            public void addCorsMappings(CorsRegistry registry) 
                registry.addMapping("/**");
            
        ;
    

这是从我项目的主要配置中获取的,即使在具有 Spring Cloud 的 netflix api 的复杂分布式系统中,这种配置也适用于我。

希望对你有帮助。

【讨论】:

以上是关于请求的资源上不存在“Access-Control-Allow-Origin”标头。离子、AngularJS、Spring Boot 1.3的主要内容,如果未能解决你的问题,请参考以下文章

django中的“请求的资源上不存在'Access-Control-Allow-Origin'标头”

如何解决请求的资源上不存在“Access-Control-Allow-Origin”标头

Http.post 请求的资源上不存在“Access-Control-Allow-Origin”标头

请求的资源发布请求上不存在“Access-Control-Allow-Origin”标头

Angular 2请求的资源上不存在“Access-Control-Allow-Origin”标头[重复]

API 请求错误 - 请求的资源上不存在“Access-Control-Allow-Origin”标头