我有一个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。响应 到预检请求未通过访问控制检查:否 "访问控制允许源"标头存在于请求的上 资源。因此,不允许访问源"http://localhost"。 响应具有 HTTP 状态代码 404。
我可以使用提供的确切链接作为托管 Web 服务所在位置的同一台计算机上的浏览器上的 url,并且一切都按预期工作。使用来自互联网探索 11 或边缘的这个 ajax 调用也可以正常工作,但是当从谷歌浏览器运行命令时,它会给出上述错误。
阅读它似乎是我的网络服务没有在其 CORS 的响应数据包中添加正确字段的问题,因此谷歌浏览器设置会捕获它并抛出错误。我尝试使用用于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 错误。
即使在将自定义标头添加到 Web 配置后,404 错误仍然存在。这最终是由于标头仍然不完全正确或 ISAPI 使用 OPTIONS 动词拦截数据包并导致一些问题,我从未弄清楚确切原因。我的解决方案是删除对 Web 配置的更改,并使用以下代码添加一个全局 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 调用失败。