Ajax Web 服务调用 - 不存在“Access-Control-Allow-Origin”标头
Posted
技术标签:
【中文标题】Ajax Web 服务调用 - 不存在“Access-Control-Allow-Origin”标头【英文标题】:Ajax Web Service Call - No 'Access-Control-Allow-Origin' header is present 【发布时间】:2015-07-17 14:30:25 【问题描述】:嘿嘿,
我知道以前有人问过这个问题,并且我已经阅读了这里每个问题的每一个答案,但似乎仍然无法让我的项目正常工作。不过,我的情况与其他问题有点不同,不确定这是否有什么不同,但我们开始吧。
我有一个由 Web 服务组成的项目。仅服务就可以正常工作,这没有问题。还有另一个项目处理 UI 部分并通过 jquery ajax 调用这些服务。它一直运行良好,因为我之前没有在 Google Chrome 上测试过这个案例。一切都可以在 Internet Explorer 上完美运行。
现在;我的 Web 服务应用程序在端口 40000 (localhost:40000) 上运行,UI 项目在其他一些随机端口上运行,但仍在 localhost 中。就像我说的,我的 ajax 调用等在 Internet Explorer 上运行良好,但在 Google Chrome 上却失败了。控制台显示以下错误:
XMLHttpRequest cannot load http://127.0.0.1:40000/abc.asmx/TheMethodName. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:17256' is therefore not allowed access. The response had HTTP status code 400.
顺便说一句,之前好像是“localhost:40000”,所以网上有帖子建议我应该把它改成IP地址而不是localhost。
无论如何,我还在我的网络服务项目中编辑了我的 web.config 文件并添加了以下内容(这没有任何意义)
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="crossDomain" crossDomainScriptAccessEnabled="true">
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://localhost:17256" />
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
<add name="Access-Control-Max-Age" value="1728000" />
</customHeaders>
</httpProtocol>
</system.webServer>
顺便说一句,如果我使用第一行:它完全失败并说响应头消息不匹配,我什至无法启动服务调用。
是的,我还编辑了我的 ajax 调用,添加了以下参数:
crossDomain: true,
现在,我在这里缺少什么?我已经为此工作了好几天,我快要失去理智了:) 改变项目的整个结构(服务 - 我的意思是 UI 样式)有点太晚了,因为已经将大量代码写入服务和用户界面项目。请帮助我很绝望! :)
干杯
编辑:
所以事实证明我需要使用 JSONP,而不是 JSON——因为它不会被访问控制所困,这很好。我可以将我的 ajax 调用转换为 JSONP 调用。但我需要另一个帮助:)
我已经编写了一个全局 ajax 方法,该方法从单独页面上的每个操作中调用,它的工作原理就像魅力一样(当然又是在 Internet Explorer 上)。现在我应该怎么做才能将此包装函数转换为 jsonp 东西?
function RemoteCall(WebService, RemoteMethod, RemoteParameters, callbackResult)
if (RemoteParameters == null || RemoteParameters == "")
RemoteParameters = " ";
var remoteCall = $.ajax(
type: "POST",
url: ProvideService(WebService, RemoteMethod),
data: RemoteParameters,
contentType: ajaxContentType,
dataType: ajaxDataType,
async: true,
crossDomain: true,
success: function (msg)
msg.header("Access-Control-Allow-Origin", "*");
callbackResult(msg.d);
,
error: function (xhr, ajaxOptions, thrownError)
callbackResult(xhr.status + '\r\n' + thrownError + '\r\n' + xhr.responseText);
);
我看到一些帖子,我应该添加一个属性为 jsonp: 'jsonp_callback' 和回调方法(这是我感到困惑的地方)。这个呢?
另一件事;我一直在将我的 json 参数作为文本发送到像
这样的变量中var jSONParams = ' UserID: "1", EmailAddress: "a@b.com" ';
我应该继续以相同的格式发送它还是应该将其转换为某种 JSON 对象或其他东西?
顺便说一句:我的全局 ajax 函数位于一个完全独立的 JS 文件中 - 但不确定它是否有任何区别......
干杯
【问题讨论】:
端点是否使用任何类型的身份验证? Windows 身份验证等? 【参考方案1】:我宁愿只启用 CORS 而不是更改所有 AJAX 调用。
您是否尝试修改 web 服务的 web.config 以添加以下行?
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
还要检查这个问题,看看 CORS / JSONP 是否更适合您 So, JSONP or CORS?
【讨论】:
【参考方案2】:解决 CORS 错误的关键是注意服务器响应中的标头。您需要下载像 Fiddler 这样的 http 流量监视器来检查这些标头。然后,您可以将它与浏览器控制台错误结合使用,以准确找出问题所在。
这是典型/成功的 200 OK CORS 响应的样子(直接取自 Fiddler):
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Vary: Accept-Encoding
Server: Microsoft-IIS/7.5
Access-Control-Allow-Origin: http://localhost:1234
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET,POST,OPTIONS
X-AspNet-Version: 4.0.30319
X-UA-Compatible: IE=edge
Persistent-Auth: false
WWW-Authenticate: Negotiate oYG2MIGzoAMKAQChCwYJKoZIgvcSAQIC...etc.
Date: Fri, 08 May 2015 01:14:37 GMT
Connection: close
Content-Length: 4711
...response body etc. etc.
如果您获得
No 'Access-Control-Allow-Origin' header is present on the requested resource
,标头要么从响应中丢失,要么以违反 Chrome 对 W3C 规范的实现的方式传递。
通过查看您的 web.config 文件,我愿意打赌它是后者。例如,这是一个包含多个条目的有效 Access Control Allow Origin 标头:
Access-Control-Allow-Origin: http://domain1.com,http://domain2.com
而您的 web.config 标头部分的配置方式将提供多个条目,这通常是无效的
Access-Control-Allow-Origin: http://localhost:17256
Access-Control-Allow-Origin: *
...尤其是在身份验证和 Access-Control-Allow-Credentials 标头被传递到安全端点的情况下:
【讨论】:
【参考方案3】:欢迎来到浏览器领域不那么酷的 CORS 问题,我有以下建议:
-
如果您可以将 Web 服务和 UI 部分托管在同一个端口上,创建一个项目并制作您的 Web 服务和 UI 子项目,那么这很容易解决这个问题。
如果您的 web 服务以 JSON 格式响应,请考虑使用 JSONP,最好为 web 服务提供 JSONP 支持。
希望对你有帮助
问候, 阿里夫·伊姆兰
【讨论】:
现在我有一个关于 JSONP 的问题,您可以在我原来的问题中看到 - 我已经编辑了它。有什么帮助吗? :) 哦,还有 PS:我不能在同一个端口上托管这些项目——这没有用,因为服务项目就像许多其他 UI 项目的提供者项目,我真的不想在同一个端口上运行所有 UI 项目 - 不确定它是否可能,因为在 IIS 中为每个端口创建了虚拟目录,并且怀疑 IIS 是否允许这样做......我想我会抓住 JSONP 的机会 - 如果我可以弄明白:) 看看这个json-jsonp-tutorial.craic.com/index.html,JSONP 对你来说并不是很难实现的东西。你能更具体地谈谈你面临的问题吗?【参考方案4】:谢谢大家的回答;
我找到了解决问题的方法。好像我没有完全注意错误信息:)
在我将 Access-Control-Allow-Origin 标头添加到我的 web.config 文件中后,我发现我开始收到一些其他错误,即 content-type 自定义标头丢失,我认为我仍然收到 CORS 错误。
所以,在我的 web.config 中添加 <add name="Access-Control-Allow-Origin" value="*" />
定义实际上首先解决了我的跨域问题!而且我还测试了以下 web.config 标头条目以允许来自端口的特定域或请求,它也像魅力一样工作 - 因为我认为这是最好的选择,因为我不会公开发布我的服务。
<add name="Access-Control-Allow-Origin" value="http://localhost:17256" />
祝大家好运,问题解决了:)
【讨论】:
您在 web.config 中添加了哪个标签?【参考方案5】:在 web.config 文件中添加以下代码。
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>
</httpProtocol>
【讨论】:
以上是关于Ajax Web 服务调用 - 不存在“Access-Control-Allow-Origin”标头的主要内容,如果未能解决你的问题,请参考以下文章
使用 jquery ajax jsonp 调用 web 服务:错误
使用带有摘要身份验证、jquery ajax 调用的 RestFul PHP Web 服务
如何使用 ASP.NET C# 在使用 ajax 完成 Web 服务时生成警报
无法从 .net 中的 Ajax 调用 .asmx Web 服务