预检的响应在角度中没有HTTP ok状态

Kal*_*nJa 21 http cors angular

我在我的服务中定义了以下get请求:

createAuthorizationHeader(user, pass) {
  let headers: HttpHeaders = new HttpHeaders;
  headers = headers.append('Accept', 'application/json, text/plain, */*');
  headers = headers.append('Authorization', 'Basic ' + btoa(user + ':' + pass));
  headers = headers.append('Content-Type', 'application/json; charset=utf-8');
    console.log(headers);
    return this.http.get(this._loginUrl, {
      headers: headers
    });
}
Run Code Online (Sandbox Code Playgroud)

结果是:

OPTIONS https://localhost:8443/delivery/all 401 ()

Failed to load https://localhost:8443/delivery/all: Response for preflight does not have HTTP ok status.

HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: null, ok: false, …}
Run Code Online (Sandbox Code Playgroud)

我也和Postman做了相同的帖子请求,但一切正常,所以本地服务器工作.

我无法弄清楚我的要求是怎么回事.

Gre*_*eek 32

CORS合同要求在飞行前OPTIONS请求中不需要身份验证.看起来你的后端需要在OPTIONS请求和GET上进行身份验证.

当您使用Postman访问后端时,您只发送一个GET.浏览器将首先发送OPTIONS请求(没有您的身份验证标头),并查找响应以具有与发出请求的页面的原点匹配的"Access-Control-Allow-Origin"标头.

如果对OPTIONS响应的响应不是2xx,或者标头不存在,或者标头的值与请求页面的起源不匹配,您将收到您遇到的错误,并且不会发出GET请求.

TLDR; 在处理登录URL时,将后端更改为不需要对OPTIONS方法进行身份验证.

  • 因此,解决方案是将后端更改为不需要对选项进行身份验证,但没有详细说明如何做到这一点?如果可能的话,请扩展。 (5认同)
  • 您是否有关于如何更新IIS以不需要对OPTIONS方法进行身份验证的任何其他信息? (4认同)

Dio*_*ues 7

如果是 .Net Web API 项目,请编辑 web.config 并删除下面的标记。

<handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
Run Code Online (Sandbox Code Playgroud)


Sud*_*kar 6

默认情况下,浏览器不允许用户执行跨源请求.

从Angular避免此错误,我们可以使用代理配置.

假设如果angular ui正在localhost:4200上工作并且它想要调用其余的端点url,例如:https:// localhost:8443/delivery/all

以下步骤将解决此问题.

  1. 在角应用程序根文件夹中创建proxy.config.json文件.(存在package.json文件的地方)代理的做法是简单地在前端应用程序运行的同一域+端口上获取浏览器请求,然后将该请求转发到后端API服务器.CORS是一个浏览器安全问题,在执行"后端到后端"通信时不适用,就像中间的代理一样.

    内容应如下所示.

    样品:

    {
        "/delivery/all/*": {
        "target": "https://localhost:8443",
        "secure": false,
        "logLevel": "debug",
        "changeOrigin": true
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    从我们的应用程序中向/ delivery/all/...发出的所有请求都将转发到https:// localhost:8443/delivery/all /

    注意:changeOrigin属性.当您在后端使用某些虚拟代理(例如使用Apache2配置)时,您肯定必须将其设置为true

  2. 运行应用程序时添加代理配置.Angular支持"--proxy-config",您可以在其中提供代理配置文件.如果您使用"npm start"选项进行测试,则必须添加"--proxy-config"选项,如下所示.它必须添加到package.json文件中.

     "scripts": {
    
    "ng": "ng",
    "start": "ng serve --proxy-config proxy.config.json",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
    }
    
    Run Code Online (Sandbox Code Playgroud)

    如果您使用"ng serve"直接运行,那么它将被修改,如下所示."ng serve --proxy-config proxy.config.json"

  3. 我们的Angular应用程序中的HTTP调用可以更改为此.服务器将自动将请求转发到" https:// localhost:8443/delivery/all ".

    this.http.get(' https:// localhost:8443/delivery/all ').map(res => res.json());

    this.http.get('/ delivery/all').map(res => res.json());

这里是链接以获取更多信息:https://sudhasoftjava.wordpress.com/2018/10/05/proxy-configuration-in-angular/


小智 5

我们所做的是为 Cors 添加自定义配置。然后通过java服务器中的安全配置来启用它。如答案中所述,该服务器仅针对直接 REST 调用启用。

@Configuration
public class CorsConfig {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
                        .allowedHeaders("*");
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

这涉及到网络安全配置:

@Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.csrf().disable()
                .antMatcher("/**")
                .authorizeRequests().and()
                .httpBasic()
                .and()
                .authorizeRequests().anyRequest().authenticated().and().cors();
    }
Run Code Online (Sandbox Code Playgroud)

  • 只需将 cors() 添加到我现有的配置中即可解决问题。 (3认同)