XMLHttpRequest 无法使用 jQuery 加载 URL

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3828982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 16:11:07  来源:igfitidea点击:

XMLHttpRequest cannot load an URL with jQuery

jqueryjsoncross-domaincors

提问by Zakaria

I'm trying to get some json data from a "remote" website. I run my web service on the 99000 port then, I launch my website on the 99001 port (http://localhost:99001/index.html).

我正在尝试从“远程”网站获取一些 json 数据。我在 99000 端口上运行我的 Web 服务,然后在 99001 端口 (http://localhost:99001/index.html) 上启动我的网站。

I get the following message:

我收到以下消息:

    XMLHttpRequest cannot load http://localhost:99000/Services.svc/ReturnPersons. Origin http://localhost:99001 is not allowed by Access-Control-Allow-Origin.

Even If I launch my web page as an HTML file, I get this:

即使我将网页作为 HTML 文件启动,我也会得到以下信息:

    XMLHttpRequest cannot load http://localhost:99000/Services.svc/ReturnPersons.Origin null is not allowed by Access-Control-Allow-Origin.

The web service returns data. I try to catch the data items like this:

Web 服务返回数据。我尝试捕捉这样的数据项:

var url = "http://localhost:99000/Services.svc/ReturnPersons";
$.getJSON(url, function (data) {
success: readData(data)
});
function readData(data) {
    alert(data[0].FirstName);
}

And I'm trying to get this structure:

我正在尝试获得这种结构:

[{"FirstName":"Foo","LastName":"Bar"},{"Hello":"Foo","LastName":"World"}]

Do you know why I'm getting this error?

你知道我为什么会收到这个错误吗?

采纳答案by CharlesLeaf

You can't do a XMLHttpRequest crossdomain, the only "option" would be a technique called JSONP, which comes down to this:

你不能做一个 XMLHttpRequest 跨域,唯一的“选项”是一种叫做 JSONP 的技术,归结为:

To start request: Add a new <script>tag with the remote url, and then make sure that remote url returns a valid javascript file that calls your callback function. Some services support this (and let you name your callback in a GET parameters).

开始请求:添加<script>带有远程 url的新标签,然后确保远程 url 返回调用回调函数的有效 javascript 文件。一些服务支持这一点(并让您在 GET 参数中命名您的回调)。

The other easy way out, would be to create a "proxy" on your local server, which gets the remote request and then just "forwards" it back to your javascript.

另一个简单的方法是在您的本地服务器上创建一个“代理”,它获取远程请求,然后将其“转发”回您的 javascript。

edit/addition:

编辑/添加:

I see jQuery has built-in support for JSONP, by checking if the URL contains "callback=?" (where jQuery will replace ? with the actual callback method). But you'd still need to process that on the remote server to generate a valid response.

通过检查 URL 是否包含“callback=?”,我看到 jQuery 内置了对 JSONP 的支持。(jQuery 将在哪里替换 ? 与实际的回调方法)。但是您仍然需要在远程服务器上处理它以生成有效的响应。

回答by Slav

In new jQuery 1.5 you can use:

在新的 jQuery 1.5 中,您可以使用:

$.ajax({
    type: "GET",
    url: "http://localhost:99000/Services.svc/ReturnPersons",
    dataType: "jsonp",
    success: readData(data),
    error: function (xhr, ajaxOptions, thrownError) {
      alert(xhr.status);
      alert(thrownError);
    }
})

回答by Hugolpz

Fiddle with 3 working solutionsin action.

摆弄 3 个有效的解决方案

Given an external JSON:

给定一个外部 JSON:

myurl = 'http://wikidata.org/w/api.php?action=wbgetentities&sites=frwiki&titles=France&languages=zh-hans|zh-hant|fr&props=sitelinks|labels|aliases|descriptions&format=json'

Solution 1: $.ajax() + jsonp:

方案一:$.ajax() + jsonp:

$.ajax({
  dataType: "jsonp",
  url: myurl ,
  }).done(function ( data ) {
  // do my stuff
});

Solution 2: $.ajax()+json+&calback=?:

方案二:$.ajax()+json+&calback=?:

$.ajax({
  dataType: "json",
  url: myurl + '&callback=?',
  }).done(function ( data ) {
  // do my stuff
});

Solution 3: $.getJSON()+calback=?:

解决方案 3: $.getJSON()+calback=?:

$.getJSON( myurl + '&callback=?', function(data) {
  // do my stuff
});

Documentations: http://api.jquery.com/jQuery.ajax/, http://api.jquery.com/jQuery.getJSON/

文档:http: //api.jquery.com/jQuery.ajax/,http: //api.jquery.com/jQuery.getJSON/

回答by Rytis

Found a possible workaround that I don't believe was mentioned.

找到了一个我认为没有提到的可能的解决方法。

Here is a good description of the problem: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

这是对问题的一个很好的描述:http: //www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

Basically as long as you use forms/url-encoded/plain text content types you are fine.

基本上只要您使用表单/url 编码/纯文本内容类型就可以了。

$.ajax({
    type: "POST",
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'text/plain'
    },
    dataType: "json",
    url: "http://localhost/endpoint",
    data: JSON.stringify({'DataToPost': 123}),
    success: function (data) {
        alert(JSON.stringify(data));
    }
});     

I use it with ASP.NET WebAPI2. So on the other end:

我将它与 ASP.NET WebAPI2 一起使用。所以在另一端:

public static void RegisterWebApi(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();

    config.Formatters.Clear();
    config.Formatters.Add(new JsonMediaTypeFormatter());

    config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
}

This way Json formatter gets used when parsing plain text content type.

这种方式在解析纯文本内容类型时使用 Json 格式化程序。

And don't forget in Web.config:

并且不要忘记在 Web.config 中:

<system.webServer>
<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Methods" value="GET, POST" />
  </customHeaders>
</httpProtocol>    

Hope this helps.

希望这可以帮助。

回答by Navin Pandit

I am using WebAPI 3 and was facing the same issue. The issue has resolve as @Rytis added his solution. And I think in WebAPI 3, we don't need to define method RegisterWebApi.

我正在使用 WebAPI 3 并面临同样的问题。随着@Rytis 添加了他的解决方案,该问题已解决。我认为在 WebAPI 3 中,我们不需要定义 method RegisterWebApi

My change was only in web.config file and is working.

我的更改仅在 web.config 文件中,并且正在运行。

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

Thanks for you solution @Rytis!

感谢您的解决方案@Rytis!