【问题标题】:Ajax Web Service Call - No 'Access-Control-Allow-Origin' header is presentAjax Web 服务调用 - 不存在“Access-Control-Allow-Origin”标头
【发布时间】: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 身份验证等?

标签: c# jquery asp.net ajax web-services


【解决方案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 问题,我有以下建议:

      1. 如果您可以将 Web 服务和 UI 部分托管在同一个端口上,创建一个项目并制作您的 Web 服务和 UI 子项目,那么这很容易解决这个问题。
      2. 如果您的 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 中添加 &lt;add name="Access-Control-Allow-Origin" value="*" /&gt; 定义实际上首先解决了我的跨域问题!而且我还测试了以下 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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-28
        • 2015-11-18
        • 2013-11-23
        • 2016-05-13
        • 2019-08-15
        • 2017-02-21
        • 2015-09-28
        • 2016-10-30
        相关资源
        最近更新 更多