0

I'm trying to read a remote file ; I'm using the example on the jquery.get() documentation page :

    var jqxhr = $.get( 'http://stackoverflow.com/feeds/question/10943544', function() {
                       alert( 'success' );
                       })
    .done(function() {
                  alert( 'second success' );
                  })
    .fail(function(jqXHR, textStatus, errorThrown) {
                  // alert( 'error' );
                  console.log('Error: (' + errorThrown + ')');
    })
    .always(function() {
    alert( 'finished' );
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

But it only triggers "fail" and "always" and I'd like to understand why ; My question is : How can I obtain a readable error? Currently, the console.log("Error: (" + errorThrown + ')'); only yields Error: ().

Bonus question: Why does it fail? How can I read a remote (RSS) file using JS/JQuery?

yPhil
  • 8,049
  • 4
  • 57
  • 83

1 Answers1

2

Your problem is one of the Same Origin Policy, which is present on most AJAX requests, and put in place as a security measure. If you look at jqXHR() you can see that readyState is 0, indicating this. Note that readyState will always be 0 when the request has failed, be it for policy restriction or a malformed request. The error message is blank because the restrictions are preventing the error message itself from triggering.

var jqxhr = $.get("http://stackoverflow.com/feeds/question/10943544", function(res) {
    alert("success");
  })
  .done(function() {
    alert("second success");
  })
  .fail(function(jqXHR, textStatus, errorThrown) {
    // alert( "error" );
    console.log("Error: (" + errorThrown + ')');
  })
  .always(function(jqXHR) {
    console.log(jqXHR);
  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

To get around this, there are a number of plugins, which are listed in this answer. It also states:

The best way to overcome this problem, is by creating your own proxy in the back-end, so that your proxy will point to the services in other domains, because in the back-end not exists the same origin policy restriction.

However, assuming you can't do that, the easiest way is to make use of CORS Anywhere proxy, as is shown in the following snippet (note that the result takes a while to come through):

$.ajaxPrefilter(function(options) {
  if (options.crossDomain && jQuery.support.cors) {
    var http = (window.location.protocol === 'http:' ? 'http:' : 'https:');
    options.url = http + '//cors-anywhere.herokuapp.com/' + options.url;
    //options.url = "http://cors.corsproxy.io/url=" + options.url;
  }
});

$.get(
  'http://stackoverflow.com/feeds/question/10943544',
  function(response) {
    console.log("> ", response);
    $("#viewer").html(response);
  }
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Hope this helps! :)

Obsidian Age
  • 41,205
  • 10
  • 48
  • 71
  • Don't really see why this is deserving of a down-vote? Keen to know to improve the answer. – Obsidian Age Oct 05 '17 at 19:39
  • 1
    I don't think it's clear enough on answering the question. *"My question is : **How can I obtain a readable error?** "* You did mention that the readystate would be 0, but, how does that translate to the given code? what else could result in a textstatus of 0? i mean, besides the fact that the actual error message is inaccessible via javascript due to the very reason an error is occuring. – Kevin B Oct 05 '17 at 19:42
  • Well you would get a `readyState` of `0` in any situation where the page is not ready to complete the request, such as a malformed or failed request. If you can't make the request, there is **no** way to get the error that I'm aware of outside of `errorThrown` (or completely re-crafting the request), as the error can't be triggered. I've updated the answer to cover this. – Obsidian Age Oct 05 '17 at 19:47