为啥仅在移动 Web 浏览器中显示 Access-Control-Allow-Origin 不允许显示 Origin?

Posted

技术标签:

【中文标题】为啥仅在移动 Web 浏览器中显示 Access-Control-Allow-Origin 不允许显示 Origin?【英文标题】:Why does it display Origin is not allowed by Access-Control-Allow-Origin only in mobile web browsers?为什么仅在移动 Web 浏览器中显示 Access-Control-Allow-Origin 不允许显示 Origin? 【发布时间】:2019-06-01 04:05:16 【问题描述】:

在我的 spring-boot+React 应用程序在桌面网络浏览器上运行良好,但是当我通过移动(我使用 iPhone)网络浏览器(如 chrome 或 safari)创建记录时,它显示 'Origin'http://www.example.com' 是Access-Control-Allow-Origin' 不允许。我已经添加了 'Cors Mappings' 像

@Configuration
public class WebMvcConfig implements WebMvcConfigurer 

    private final long MAX_AGE_SECS = 3600;

    @Override
    public void addCorsMappings(CorsRegistry registry) 
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("HEAD", "OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE")
                .maxAge(MAX_AGE_SECS);
    

谁能帮我解决这个问题?

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
        securedEnabled = true,
        jsr250Enabled = true,
        prePostEnabled = true
)
public class SecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    CustomUserDetailsService customUserDetailsService;

    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() 
        return new JwtAuthenticationFilter();
    

    @Override
    public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception 
        authenticationManagerBuilder
                .userDetailsService(customUserDetailsService)
                .passwordEncoder(passwordEncoder());
    

    @Bean(BeanIds.AUTHENTICATION_MANAGER)
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception 
        return super.authenticationManagerBean();
    

    @Bean
    public PasswordEncoder passwordEncoder() 
        return new BCryptPasswordEncoder();
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 

        http
                .cors()
                    .and()
                .csrf()
                    .disable()
                .exceptionHandling()
                    .authenticationEntryPoint(unauthorizedHandler)
                    .and()
                .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.GET, "/api/brands/**", "/api/users/**")
                    .permitAll()
                    .antMatchers(
                        "/",
                        "/favicon.ico",
                        "/**/*.png",
                        "/**/*.gif",
                        "/**/*.svg",
                        "/**/*.jpg",
                        "/**/*.html",
                        "/**/*.css",
                        "/**/*.js"
                        ) .permitAll()
                    .antMatchers("/api/auth/**")
                        .permitAll()
                    .antMatchers("/api/user/checkUsernameAvailability", "/api/user/checkEmailAvailability")
                        .permitAll()
                        .antMatchers("/api/brands/**").permitAll()      
                        .antMatchers("/api/familys/**").permitAll()
                        .antMatchers("/api/models/**").permitAll()
                    .anyRequest()
                        .authenticated();

           http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
           


【问题讨论】:

【参考方案1】:

删除 WebMvcConfig 类 并在您的 SecurityConfig 类 中添加一个名为 corsConfigurationSource 的 bean,它将能够设置标头/方法并允许使用“*”的任何来源,但如果您想允许一个特定的来源,你可以添加它。

@Bean
public CorsConfigurationSource corsConfigurationSource() 
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("*"));
    configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
    configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type", "x-auth-token"));
    configuration.setExposedHeaders(Arrays.asList("x-auth-token"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;

【讨论】:

是否需要更改方法的返回类型?因为 'source' 是 UrlBasedCorsConfigurationSource 类型。而且,我需要将此 bean 添加到 SecurityConfig 类中,不是吗? 是的。您需要在 SecurityConfig 类中添加此 bean。您不需要更改此 bean 中的某些内容.. 但它要求将返回类型更改为 'UrlBasedCorsConfigurationSource' 不是因为UrlBasedCorsConfigurationSource类实现了CorsConfigurationSource这个接口,所以没问题docs.spring.io/spring-framework/docs/current/javadoc-api/org/… 是的,你是对的。不需要改变返回类型。但是,我尝试将给定的 bean 放入 SecurityConfig 类。但是,在移动网络浏览器上仍然出现同样的错误。

以上是关于为啥仅在移动 Web 浏览器中显示 Access-Control-Allow-Origin 不允许显示 Origin?的主要内容,如果未能解决你的问题,请参考以下文章

手机移动端web开发的时候为啥要用js跳转链接来代替a标签的跳转?

Blazor 仅在移动设备上显示组件

通过 Microsoft Access 访问 Sharepoint 库

如何在 MS-Access 的表单上显示 Web 浏览器控件中的表格字段内容?

仅在移动设备上进行基础画布外导航?

用showwindow函数显示窗体,不能显示按钮,且无法关闭,为啥