可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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).
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:
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:
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?
回答1:
You can\'t do a XMLHttpRequest crossdomain, the only \"option\" would be a technique called JSONP, which comes down to this:
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).
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.
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.
回答2:
In new jQuery 1.5 you can use:
$.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);
}
})
回答3:
Fiddle with 3 working solutions in action.
Given an external 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({
dataType: \"jsonp\",
url: myurl ,
}).done(function ( data ) {
// do my stuff
});
Solution 2: $.ajax()+json+&calback=?:
$.ajax({
dataType: \"json\",
url: myurl + \'&callback=?\',
}).done(function ( data ) {
// do my stuff
});
Solution 3: $.getJSON()+calback=?:
$.getJSON( myurl + \'&callback=?\', function(data) {
// do my stuff
});
Documentations: http://api.jquery.com/jQuery.ajax/ , http://api.jquery.com/jQuery.getJSON/
回答4:
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
Basically as long as you use forms/url-encoded/plain text content types you are fine.
$.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:
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.
And don\'t forget in 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.
回答5:
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
.
My change was only in web.config file and is working.
<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!