2011-01-04 1 views
2

Я пишу приложение javascript, которое будет размещаться по протоколу file: (т. Е. Приложение представляет собой просто папку html, css и javascript, сидящую где-нибудь на моем жестком диске водить машину). Когда я пытаюсь выполнить обычные запросы XHR, они терпят неудачу из-за того же самого аффинита политики происхождения.Создание json/jsonp xhr запросов на файл: protocol

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

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

+0

У вас есть браузеры? – Hemlock

+2

Он должен работать как можно больше браузеров. – erikvold

+0

С CORS он никогда не будет работать, потому что вы не можете вернуть заголовок 'Access-Control-Allow-Origin', запросив хост' file: '. – inf3rno

ответ

5

Это своего рода задача с топором, но это даст вам ваши динамические обратные вызовы. В основном это связано с тем, что переводы 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' 
}); 
+0

@Erik я * не * создание это предположение. Я действительно жду возвращения до отправки следующего запроса. Вместо этого я делаю предположение, что запрос будет быстрым. Заказ, однако, не будет проблемой. – Hemlock

+0

@ Erik ... Полагаю, я тоже предполагаю, что ошибки не будет;) – Hemlock

+0

Это достойное решение, мне бы хотелось увидеть тот, который не требовал запросов в очереди, но это не так, t настолько плохо, когда дело доходит до использования 'file:', как вы говорите. – erikvold

-2

«Когда я пытаюсь нормальные запросы XHR они терпят неудачу из-за того же происхождения AFAICT политики»

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

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

+0

Это работает на Firefox btw – erikvold

+0

Это ошибка из Google Chrome: XMLHttpRequest не может загрузить файл: /// C: /ColdFusion8/wwwroot/test-app/data/index.json. Происхождение null не разрешено Access-Control-Allow-Origin. – erikvold

+2

@ Erik: Я полагаю, что для «практических» целей вы правы. Однако официально спецификация XMLHttpRequest не упоминает файловый протокол (http://www.w3.org/TR/XMLHttpRequest/) - «некоторые реализации поддерживают протоколы в дополнение к HTTP и HTTPS, но эта функциональность не охватываемых настоящей спецификацией ». Вы можете сказать, что его XMLHttpRequest не удалось из-за той же политики происхождения - я говорю, что это не был «обычный XHR-запрос» ...потому что это будет связано с HTTP или HTTPS ... согласно официальной спецификации (или википедии). Я просто педантичен. :) – Gerrat

1

Chrome имеет очень жесткие ограничения на делать Ajax звонки из файла: // URL, по соображениям безопасности. Они знают, что это ломает приложения, которые запускаются локально, и есть a lot of debate об альтернативах, но так оно и есть сегодня.

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

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