Выполнение запросов json/jsonp xhr к файлу: протокол

Я пишу приложение Javascript, которое будет размещено на file: протокол (то есть: приложение - это просто папка html, css и javascript, которая находится где-то на моем жестком диске). Когда я пробую нормальные запросы XHR, они терпят неудачу из-за одной и той же политики происхождения.

Итак, мой вопрос заключается в следующем: как лучше всего запросить файлы json / jsonp с помощью приложения, как описано выше?

Примечание. Пока у меня есть все мои файлы jsonp с использованием жестко закодированных функций обратного вызова, но я хотел бы иметь возможность использовать функции динамического обратного вызова для этих запросов. Есть ли способ сделать это?

3 ответа

Решение

Это довольно сложная работа, но она даст вам ваши динамические обратные вызовы. В основном это рассчитывает на то, что file: переводы будут довольно быстрыми. Он устанавливает очередь запросов и отправляет их по одному за раз. Это был единственный способ выяснить, чтобы убедиться, что правильный ответ и обратный вызов могут быть связаны (в гарантированном порядке). Надеюсь, кто-то может придумать лучший способ, но без возможности динамически генерировать ответы, это лучшее, что я могу сделать.

var JSONP = {
  queue: [],
  load: function(file, callback, scope) {
      var head = document.getElementsByTagName('head')[0];
      var script = document.createElement('script');
      script.type = "text/javascript";
      script.src = file;
      head.appendChild(script);
  },

  request: function(file, callback, scope) {
      this.queue.push(arguments);
      if (this.queue.length == 1) {
          this.next();
      }
  },

  response: function(json) {
      var requestArgs = this.queue.shift();
      var file = requestArgs[0];
      var callback = requestArgs[1];
      var scope = requestArgs[2] || this;
      callback.call(scope, json, file);

      this.next();
  },

  next: function() {
      if (this.queue.length) {
          var nextArgs = this.queue[0];
          this.load.apply(this, nextArgs);
      }
  }

};

Это то, что я сделал, чтобы проверить

window.onload = function() {
  JSONP.request('data.js', function(json, file) { alert("1 " + json.message); });
  JSONP.request('data.js', function(json, file) { alert("2 " + json.message); });
}

Data.js

JSONP.response({
  message: 'hello'
});

В целях безопасности Chrome имеет очень строгие ограничения на выполнение вызовов ajax из файла:// url. Они знают, что это ломает приложения, которые запускаются локально, и было много споров об альтернативах, но так оно и есть сегодня.

Ajax отлично работает по URL-адресам файлов в Firefox, просто имейте в виду, что код возврата не является кодом состояния http; т. е. 0 - это успех, а не 200-299 + 304.

IE обрабатывает эти проблемы безопасности по-разному, как в Chrome, так и в Firefox, и я ожидаю, что у других браузеров будут свои подходы. Граница между веб-приложениями и настольными приложениями - очень проблемная территория.

"Когда я пытаюсь выполнить нормальные запросы XHR, они терпят неудачу из-за той же политики происхождения"

... нет, я думаю, что они терпят неудачу, потому что запрос XHR использует HTTP или HTTP для запроса ресурса на веб-сервере. (см. http://en.wikipedia.org/wiki/XMLHttpRequest).

Если вы не связываетесь с веб-сервером, вы не можете (успешно) делать запросы XHR.

Другие вопросы по тегам