不允许使用 CORS 使用 angularjs 进行跨域请求的 DELETE 请求

Posted

技术标签:

【中文标题】不允许使用 CORS 使用 angularjs 进行跨域请求的 DELETE 请求【英文标题】:DELETE request not allowed using CORS for cross domain request with angularjs 【发布时间】:2016-09-02 03:11:53 【问题描述】:

我根据http://bitoftech.net/的demo创建了一个站点

我已经让一切正常工作,但是,由于某些原因,当我的 api 发出 OPTION 请求时,除了 POST 或 GET 之外的请求被阻止。

我收到以下请求的以下错误:

http://localhost:26264/api/photo/facebook_reactions-02.png

XMLHttpRequest cannot load http://localhost:26264/api/photo/facebook_reactions-02.png. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:32150' is therefore not allowed access. The response had HTTP status code 404

执行以下代码时收到上述错误:

'remove':  method: 'DELETE', url: serviceBase + 'api/photo/:fileName', params:  name: '@fileName'  

本地主机是正确的。如果我发布包含我可以通过的数据的帖子。例如。当我想通过 POST 更新用户数据时。

演示应用还包含一个拦截器 authInterceptorService.js,以便我的请求在发送之前得到处理。

var _request = function (config) 

    config.headers = config.headers || ;

    var authData = localStorageService.get('authorizationData');
    if (authData) 
        config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
        config.headers.Authorization = 'Bearer ' + authData.token;
    

    return config;

但是当我查看请求时:

OPTIONS /api/photo/facebook_reactions-02.png HTTP/1.1
Host: localhost:26264
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: DELETE
Origin: http://localhost:32150
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/50.0.2661.94 Safari/537.36
Access-Control-Request-Headers: accept, authorization
Accept: */*
Referer: http://localhost:32150/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: nl,en-US;q=0.8,en;q=0.6,fr;q=0.4

我没有单独看到内容类型,也没有将其视为 Access-Control-Request-Headers 的一部分。 奇怪的是,在回复中我看到以下内容:

Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS, TOKEN

所以我认为我的请求通过了。但是,它没有......

为了完整起见,我的 StartUp.cs:

[assembly: OwinStartup(typeof(AngularJSAuthentication.API.Startup))]

[...]

    public void Configuration(IAppBuilder app)
    
        HttpConfiguration config = new HttpConfiguration();

        ConfigureOAuth(app);

        WebApiConfig.Register(config);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(config);
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<AuthContext, Migrations.Configuration>());

    

    public void ConfigureOAuth(IAppBuilder app)
    
        //use a cookie to temporarily store information about a user logging in with a third party login provider
        app.UseExternalSignInCookie(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ExternalCookie);
        OAuthBearerOptions = new OAuthBearerAuthenticationOptions();

        OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions() 

            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
            Provider = new SimpleAuthorizationServerProvider(),
            RefreshTokenProvider = new SimpleRefreshTokenProvider()
        ;

        // Token Generation
        app.UseOAuthAuthorizationServer(OAuthServerOptions);
        app.UseOAuthBearerAuthentication(OAuthBearerOptions);
    

还有 web.config:

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <handlers>
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="UrlRoutingModule-4.0" path="*." verb="*" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
    </handlers>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS, TOKEN" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>

我忽略了什么以允许 DELETE(以及 PUT)请求通过?

【问题讨论】:

【参考方案1】:

发现问题!

当尝试使用以扩展名结尾的字符串(例如图像)执行 OPTIONS/DELETE 请求时,如以下请求:

http://localhost:26264/api/photo/facebook_reactions-02.png

不允许这样做,因为它无法将其映射到 web api 控制器方法,即

    [HttpDelete]
    [Route("fileName")]
    public async Task<IHttpActionResult> Delete(string fileName)

我认为这是因为逻辑认为我想要请求图像。

为了绕过这一点,我将点更改为破折号,并在我的代码中进行如下替换:

        var lastDashPosition = fileName.LastIndexOf('-');

        var fileNameSegment = fileName.Substring(0, lastDashPosition);
        var extensionSegment = fileName.Substring(lastDashPosition+1);

        fileName = string.Format("0.1", fileNameSegment, extensionSegment);

按照上述,我照常处理文件:

        if (!photoManager.FileExists(fileName))
        
            return NotFound();
        

        var result = await photoManager.Delete(fileName);

        if (result.Successful)
        
            return Ok(
                new 
                        message = result.Message
                    
                );
        
        else
        
            return BadRequest(result.Message);
        

上面的工作就像一个魅力,因为你需要被授权执行删除并且它是我希望删除的图像,我可以安全地假设字符串的最后一道菜是我必须用点替换的破折号。

【讨论】:

以上是关于不允许使用 CORS 使用 angularjs 进行跨域请求的 DELETE 请求的主要内容,如果未能解决你的问题,请参考以下文章

我正在使用 angularjs 和 django-cors-headers 然后给出“这对于需要预检的跨域请求是不允许的。”

即使 CORS 不允许标头值,Angularjs 也会继续进行服务器调用

CORS 适用于 chrome 但不适用于 firefox、angularjs

只允许我的域使用 CORS?

使用 Eve 和 AngularJS 的 CORS 问题

AngularJS 的 CORS 错误仅在 FireFox 中发布