开发者

jqXHR - http-status-code-403 (but the statuscode is 0)

开发者 https://www.devze.com 2023-02-25 17:20 出处:网络
i get the statuscode 0 ... but it is the code 403. Can someone tell me what the problem is? JQUERY 开发者_如何学JAVAvar jqxhr = $.ajax({

i get the statuscode 0 ... but it is the code 403. Can someone tell me what the problem is?

JQUERY

开发者_如何学JAVA
  var jqxhr = $.ajax({
        url: 'http://gdata.youtube.com/feeds/api/users/bernd/favorites?alt=json',
        dataType: 'json'
    }).success(function(xhr) {
        alert(xhr.status);
    }).error(function(xhr) {
        alert(xhr.status);
        return false;
    })

DEMO -> http://jsfiddle.net/QFuBr/

Thanks in advance!

Peter


The server gives a 403 error to a browser, because you don't have permission to access the resource, because of the error message reported ("Favorites of requested user are not public.").

However, the server doesn't even get the request in the jsFiddle example.

You aren't allowed to make cross-browser AJAX requests. This is called the same-origin policy. It is for security reasons, to prevent malicious coders from doing unpleasant things without your knowledge. It's a blunt tool, but an effective one.

When you don't even get as far as sending a request to the server, there is no status code. This gets reported by the XMLHTTPRequest object (and its jqXHR wrapper) as 0.

Basically, you can't do what you're trying to do in the browser.

If you need the browser to access data like this asynchronously, you'll need to write a wrapper on your server to fetch the information from the remote server and feed it to the browser. There is a workaround (it's called JSONP – JSON with Padding) but I don't believe YouTube supports it.


Edit: Per gradbot's answer, it is possible to do a JSONP request by changing your code to set dataType to jsonp.

However, you won't now be able to use xhr.status. This is because JSONP does not use the XHR object, so there is no status available to check.

Here's a working example using the feed gradbot suggested. Note that the result object is passed to the handler, rather than the jqXHR object.


You need to set dataType: "jsonp" and you need to be logged in as the user you are trying to get favorites from. In this case I use my own username grabot and the alert comes back as success.

If you don't have a valid cookie for the account your trying to access then the api call will return a 403 with the content "Favorites of requested user are not public."

$(function() {
    var jqxhr = $.ajax({
        url: 'http://gdata.youtube.com/feeds/api/users/gradbot/favorites?alt=json',
        dataType: 'jsonp'
    }).success(function(data, status) {
        alert(status);
    }).error(function(xhr) {
        alert(xhr.status);
    })
});


The 403 is because you need to provide credentials for the user whose videos are being accessed. Assuming correct credentials are supplied, the request will still fail because of cross-domain restrictions.

In most cases, status code 0 implies that the request could not be sent to the server. Here's what the Chrome console logs show for your fiddle example.

XMLHttpRequest cannot load http://gdata.youtube.com/feeds/api/users/bernd/favorites?alt=json. Origin http://fiddle.jshell.net is not allowed by Access-Control-Allow-Origin.

Youtube, in-fact all Google Data API's support JSONP but to use it, you have to pass an alt parameter with the value json-in-script and specify the dataType as jsonp. jQuery will supply the callback parameter for you. Based on empirical testing, it appears that Youtube doesn't care about the alt parameter to be specifically json-in-script. As long as a callback parameter is specified, the alt parameter can take just the value json.

http://gdata.youtube.com/feeds/api/users/gradbot/favorites?alt=json http://gdata.youtube.com/feeds/api/users/gradbot/favorites?alt=json&callback=foo

Here's a working example for a publicly accessible feed.

$.ajax({
    url: 'http://gdata.youtube.com/feeds/mobile/videos?alt=json-in-script',
    dataType: 'jsonp',
    success: function(data) {
        // do something with data
    }
});


You can't do cross-domain requests(be it GET or POST) due to security restrictions in most modern browsers.

If you still want to fetch data from other domain consider using a reverse proxy that you install on you server and send all requests through. For browser it will still look like data comes from same domain.

One of the most popular ones is mod_reverse in Apache but there are other alternatives depending on what your server environment is.

Another alternative is to user JSONP if Google API supports it.

0

精彩评论

暂无评论...
验证码 换一张
取 消