PK jsX?* scriptRequest.jsvar CallbackRegistry = {}; // реестр // при успехе вызовет onSuccess, при ошибке onError function scriptRequest(url, onSuccess, onError) { var scriptOk = false; // флаг, что вызов прошел успешно // сгенерировать имя JSONP-функции для запроса var callbackName = 'cb' + String(Math.random()).slice(-6); // укажем это имя в URL запроса url += ~url.indexOf('?') ? '&' : '?'; url += 'callback=CallbackRegistry.' + callbackName; // ..и создадим саму функцию в реестре CallbackRegistry[callbackName] = function(data) { scriptOk = true; // обработчик вызвался, указать что всё ок delete CallbackRegistry[callbackName]; // можно очистить реестр onSuccess(data); // и вызвать onSuccess }; // эта функция сработает при любом результате запроса // важно: при успешном результате - всегда после JSONP-обработчика function checkCallback() { if (scriptOk) return; // сработал обработчик? delete CallbackRegistry[callbackName]; onError(url); // нет - вызвать onError } var script = document.createElement('script'); // в старых IE поддерживается только событие, а не onload/onerror // в теории 'readyState=loaded' означает "скрипт загрузился", // а 'readyState=complete' -- "скрипт выполнился", но иногда // почему-то случается только одно из них, поэтому проверяем оба script.onreadystatechange = function() { if (this.readyState == 'complete' || this.readyState == 'loaded') { this.onreadystatechange = null; setTimeout(checkCallback, 0); // Вызвать checkCallback - после скрипта } } // события script.onload/onerror срабатывают всегда после выполнения скрипта script.onload = script.onerror = checkCallback; script.src = url; document.body.appendChild(script); }PK jsX|%&* server.jsvar http = require('http'); var url = require('url'); var static = require('node-static'); var file = new static.Server('.', { cache: 0 }); function accept(req, res) { var urlParsed = url.parse(req.url, true); if (urlParsed.pathname == '/user') { var id = urlParsed.query.id; var callback = urlParsed.query.callback; res.setHeader('Content-Type', 'application/javascript; charset=utf-8'); var user = { name: "Вася", id: id }; res.end(callback + '(' + JSON.stringify(user) + ')'); } else { file.serve(req, res); } } // ------ запустить сервер ------- if (!module.parent) { http.createServer(accept).listen(8080); } else { exports.accept = accept; }PK jsX- index.html
PK jsX?* scriptRequest.jsPK jsX|%&* server.jsPK jsX- index.htmlPK Z