我正试图从“远程”网站获取一些json数据。 我在99000端口上运行我的Web服务然后,我在99001端口上启动我的网站(http:// localhost:99001 / index.html)。
我收到以下消息:
XMLHttpRequest cannot load http://localhost:99000/Services.svc/ReturnPersons. Origin http://localhost:99001 is not allowed by Access-Control-Allow-Origin.
即使我将我的网页作为HTML文件启动,我也明白了:
XMLHttpRequest cannot load http://localhost:99000/Services.svc/ReturnPersons.Origin null is not allowed by Access-Control-Allow-Origin.
Web服务返回数据。我尝试捕获这样的数据项:
var url = "http://localhost:99000/Services.svc/ReturnPersons";
$.getJSON(url, function (data) {
success: readData(data)
});
function readData(data) {
alert(data[0].FirstName);
}
我正试图获得这种结构:
[{"FirstName":"Foo","LastName":"Bar"},{"Hello":"Foo","LastName":"World"}]
你知道我为什么会收到这个错误吗?
答案 0 :(得分:39)
你不能做一个XMLHttpRequest交叉域,唯一的“选项”是一种名为JSONP的技术,它归结为:
要启动请求:使用远程网址添加新的<script>
标记,然后确保远程网址返回调用您的回调函数的有效javascript文件。有些服务支持此功能(并允许您在GET参数中命名回调)。
另一个简单的方法是在本地服务器上创建一个“代理”,它获取远程请求,然后将其“转发”回你的javascript。
修改/添加:强>
我看到jQuery内置了对JSONP的支持,通过检查URL是否包含“callback =?” (jQuery将用实际的回调方法替换?)但是你仍然需要在远程服务器上处理它以生成有效的响应。
答案 1 :(得分:34)
在新的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);
}
})
答案 2 :(得分:19)
Fiddle with 3 working solutions 正在行动中。
给定外部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'
解决方案1:$ .ajax()+ jsonp:
$.ajax({
dataType: "jsonp",
url: myurl ,
}).done(function ( data ) {
// do my stuff
});
解决方案2:$ .ajax()+ json +&amp; calback =?:
$.ajax({
dataType: "json",
url: myurl + '&callback=?',
}).done(function ( data ) {
// do my stuff
});
解决方案3:$ .getJSON()+ calback =?:
$.getJSON( myurl + '&callback=?', function(data) {
// do my stuff
});
文档:http://api.jquery.com/jQuery.ajax/,http://api.jquery.com/jQuery.getJSON/
答案 3 :(得分:6)
找到了一个我不相信的可行解决方法。
这是对问题的一个很好的描述: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
基本上只要您使用表单/网址编码/纯文本内容类型就可以了。
$.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));
}
});
我在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"));
}
这样,在解析纯文本内容类型时会使用Json格式化程序。
不要忘记在Web.config中:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST" />
</customHeaders>
</httpProtocol>
希望这有帮助。
答案 4 :(得分:0)
我正在使用WebAPI 3并且面临同样的问题。随着@Rytis添加他的解决方案,问题已得到解决。我认为在WebAPI 3中,我们不需要定义方法RegisterWebApi
。
我的更改仅在web.config文件中正在运行。
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST" />
</customHeaders>
</httpProtocol>
感谢您解决@Rytis!