Web API + jQuery AJAX DELETE 请求返回 404

Posted

技术标签:

【中文标题】Web API + jQuery AJAX DELETE 请求返回 404【英文标题】:Web API + jQuery AJAX DELETE request returning 404 【发布时间】:2015-02-17 18:17:00 【问题描述】:

当我请求 PUT 或 DELETE 时,我的 ASP.NET WebAPI 和 MVC 应用程序返回 404 错误。它曾经返回 405,但我通过启用 CORS 解决了这个问题。我尝试了各种不同的解决方案(禁用 WebDAV、更改路由、将查询字符串放入请求中),但似乎没有一个对我有用。我希望我只是错过了一些非常简单的事情。以下是我的应用程序中每个相关文件的相关简化代码:

jQuery AJAX 请求:

$.ajax(
    url: "api/Signout?id=3",
    type: "DELETE",
    crossDomain: true,
);

SignoutController(GET 和 POST 方法从这里可以正常工作):

public void Delete([FromUri] int id)

    //Do things

WebApiConfig 路由:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/controller/id",
    defaults: new  id = RouteParameter.Optional 
);

//For another part of the application
config.Routes.MapHttpRoute(
    name: "SaveSignout",
    routeTemplate: "api/controller/signout"
);

Web.config:

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <clear />
      <add name="Access-Control-Allow-Origin" value="*" />
      <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
      <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    </customHeaders>
  </httpProtocol>
  <modules>
    <remove name="FormsAuthenticationModule" />
    <remove name="WebDAVModule"/>
  </modules>
  <handlers>
    <remove name="WebDAV" />
    <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
    <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" />
  </handlers>
</system.webServer>

RouteConfig.cs(在 SO 的其他地方看到这个)

routes.IgnoreRoute("*x", new  x = @".*\.asmx(/.*)?" ); 

Fiddler DELETE 请求(简化​​的referer):

DELETE /api/Signout?id=45 HTTP/1.1
Host: localhost:51301
Connection: keep-alive
Cache-Control: no-cache
Authorization: Negotiate (large base64 here)
Pragma: no-cache
Accept: */*
Origin: http://localhost:51301
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/33.0.1750.154 Safari/537.36
Referer: http://localhost:51301/Home/Controller/Id
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8

提琴手回应:

HTTP/1.1 404 Not Found
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/8.0
X-SourceFiles: =?UTF-8?B? (base64 of full local path to api/Signout)
Persistent-Auth: true
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
WWW-Authenticate: Negotiate oRswGaADCgEAoxIEEAEAAABDh+CIwTbjqQAAAAA=
Date: Tue, 17 Feb 2015 18:05:18 GMT
Content-Length: 4966

这只是我遇到的各种“解决方案”,显然所有这些“解决方案”都适用于相关人员。我哪里错了?

【问题讨论】:

url: "api/Signouts/54" 有效吗?我不确定 不幸的是,这给了我同样的结果。 您可以尝试在控制器中的特定功能上使用 [HttpDelete] 和 [HttpPut] 注释吗? 你有“Signout”控制器,但是在你的 jQuery 中你有“Signouts”... @Marcin...你是对的...我明天再回来时必须修复它。很确定这将是解决方案,谢谢! 【参考方案1】:

默认情况下 IIS 不处理 DELETE 请求:Web.Config 中定义的 system.webServer 处理程序可以设置当您网站的应用程序池具有集成 (IIS7) 或经典 (ISAPI 32) 的“托管管道模式”时如何处理请求和 64 位口味)。在您的示例中,仅控制 ISAPI 64 位。以下显示了其他变体。

<system.webServer>
    <handlers>
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.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="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>

参考:

Related Answer on SO Extensionless URL Handler Background on MSDN Blog Background on Classic/ISAPI vs Integrated on SO

【讨论】:

【参考方案2】:

Richaux 是对的,IIS 默认不服务 DELETE、PUT 等请求。但是,该答案中的 Web.config 部分显示了它是如何在 MVC4 模板中完成的。从 MVC5 模板创建 MVC5 Web API 项目时,您将看到为所有动词注册处理程序的相关部分:

<system.webServer>
   <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>
</system.webServer>

【讨论】:

以上是关于Web API + jQuery AJAX DELETE 请求返回 404的主要内容,如果未能解决你的问题,请参考以下文章

需要使用 jQuery Ajax 使用 Web API - 跨域资源共享 (CORS) 问题

如何实现一个 jquery ajax 表单,它通过 php 请求从 web api 请求信息?

如何使用 jQuery Ajax 调用从 ASP.NET Web Api 下载 CSV 文件

jQuery Datatables AJAX 请求未正确命中 Web API

JQuery Ajax POST 到 Web API 返回 405 Method Not Allowed

Web API + jQuery AJAX DELETE 请求返回 404