如何使用 Web 服务和 jQuery Ajax 启用 CORS

Posted

技术标签:

【中文标题】如何使用 Web 服务和 jQuery Ajax 启用 CORS【英文标题】:How to enable CORS with Web Service and jQuery Ajax 【发布时间】:2018-01-31 06:35:57 【问题描述】:

我有一个 WebService (.asmx) 页面,其中包含许多我想从另一个网页运行的功能。我想使用 ajax 来调用函数的网页来自与 Web 服务不同的来源。当我尝试以下 ajax 调用时:

$.ajax(
        type: "POST",
        url: "http://192.168.18.218/WebSite/Pages/DBQuery.asmx/GetTestList",
        crossDomain: true,
        contentType: 'application/json; charset=utf-8',
        data: JSON.stringify(
            'filterID': 0
        ),
        dataType: "json",
        success: function (data)
        
            data = JSON.parse(data.d);
            console.log(data);
        
    );

我收到以下错误:

XMLHttpRequest 无法加载 http://192.168.18.218/WebSite/Pages/DBQuery.asmx/GetTestList。回复 预检请求未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此,Origin 'http://localhost' 不允许访问。 响应的 HTTP 状态代码为 404。

我可以在托管 Web 服务的同一台机器上的浏览器上使用作为 url 提供的确切链接,并且一切都按预期工作。使用来自 internet explore 11 或 edge 的这个 ajax 调用也可以正常工作,但是从 google chrome 运行命令时会出现上述错误。

阅读这似乎是我的网络服务没有在其响应数据包中添加正确字段的问题,因此谷歌浏览器设置会捕获它并引发错误。我已尝试编写用于 Web API 的代码以启用 CORS(请参阅以下代码块)。

public static void Register(HttpConfiguration config)
    
        //TODO: determine acceptable origins
        var corsAttr = new EnableCorsAttribute("*", "*", "*"); //accept all origins, headers, and methods
        config.EnableCors(corsAttr); //enable cross origin requests
    

这似乎不起作用,我找不到使用 Web 服务而不是 Web API 来解决此问题的文档。如何修复 Web 服务和/或 ajax 调用以正确启用 CORS?

编辑 将以下代码行添加到 Web 配置文件可解决未添加标头的 CORS 部分的问题:

    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Headers" value="*" />
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="*" />
      </customHeaders>
    </httpProtocol>

但是,我仍然收到 404 错误。在托管 Web 服务的机器上测试 ajax 调用,ajax 按预期正常工作。但是,跨域运行时,出现 404 错误。

【问题讨论】:

【参考方案1】:

即使将自定义标头添加到 Web 配置,404 错误仍然存​​在。这最终是由于标头仍未完全正确或 ISAPI 使用 OPTIONS 动词拦截数据包并导致一些我从未弄清楚确切原因的问题。我的解决方案是删除对 web 配置的更改,并使用以下代码添加一个 Global asax 文件:

<%@ Application Language="C#"%>

<script RunAt="server">
    void Application_BeginRequest(object sender, EventArgs e)
    
        var context = HttpContext.Current;
        var response = context.Response;

        // enable CORS
        response.AddHeader("Access-Control-Allow-Origin", "*");

        if (context.Request.HttpMethod == "OPTIONS")
        
            response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
            response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
            response.End();
        
    
</script>

这可确保数据包具有正确的标头。您必须删除我在问题中提到的 Web 配置部分,因为它会添加它们两次,这也会导致 ajax 调用失败。

【讨论】:

在 2021 年,这仍然对我有用。这是一个直截了当的解决方案,我必须注意您必须从 web.config 文件中删除重复信息并且它有效。因为我需要将 web 服务用于 android 应用程序后端。

以上是关于如何使用 Web 服务和 jQuery Ajax 启用 CORS的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jQuery AJAX 发布到 RESTful Web 服务?

如何在 asp.net Web 应用程序中使用 jquery ajax 使用 Web 服务

使用带有摘要身份验证、jquery ajax 调用的 RestFul PHP Web 服务

使用 JSON 从 AJAX 和 JQuery 调用简单的 Web 服务(.asmx 文件) - 解析错误

如何从 Java Rest Web 服务返回 ajax 值?

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