Можно ли сделать безопасный запрос JSONP?

Мне нужно поддерживать новые браузеры.

Мне приходится полагаться на внешнюю службу для предоставления данных JSONP, у меня нет этой службы, и она не позволяет CORS.

Мне очень непросто доверять запросам JSONP с внешнего сервера, поскольку они могут запускать произвольный код на моем конце, что позволит им отслеживать моих пользователей и даже красть их информацию.

Мне было интересно, есть ли способ создать запрос JSONP, который также безопасен?

(Связано: Как надежно защищать публичные запросы JSONP?, но не с новой релаксацией браузера)

ПРИМЕЧАНИЕ: Я спросил/ответил на вопрос Q & style, но я очень открыт для других идей.

Ответ 1

Да

Это возможно. Один из способов сделать это - использовать WebWorkers. Код, запущенный в WebWorkers, не имеет доступа к DOM или другому JavaScript-коду, на котором работает ваша страница.

Вы можете создать WebWorker и выполнить с ним запрос JSONP, а затем завершить его, когда закончите.

Процесс выглядит примерно так:

  • Создайте WebWorker из блоба с URL-адресом для запроса

  • Используйте importScripts для загрузки запроса JSONP с помощью локального обратного вызова

  • Когда этот обратный вызов выполняется, отправьте сообщение обратно на script, который, в свою очередь, будет выполнять фактическое сообщение обратного вызова с данными.

Таким образом, у злоумышленника не будет никакой информации о DOM.

Вот примерная реализация:

//   Creates a secure JSONP request using web workers.
//   url - the url to send the request to
//   data - the url parameters to send via querystring
//   callback - a function to execute when done
function jsonp(url, data, callback) {
    //support two parameters
    if (typeof callback === "undefined") {
        callback = data;
        data = {};
    }
    var getParams = ""; // serialize the GET parameters
    for (var i in data) {
        getParams += "&" + i + "=" + data[i];
    }
    //Create a new web worker, the worker posts a message back when the JSONP is done
    var blob = new Blob([
        "var cb=function(val){postMessage(val)};" +
        "importScripts('" + url + "?callback=cb" + getParams + "');"],{ type: "text/javascript" });
    var blobURL = window.URL.createObjectURL(blob);
    var worker = new Worker(blobURL);

    // When you get a message, execute the callback and stop the WebWorker
    worker.onmessage = function (e) {
        callback(e.data);
        worker.terminate();
        };
    worker.postMessage(getParams); // Send the request
    setTimeout(function(){
        worker.terminate();//terminate after 10 seconds in any case.
    },10000);
};

Вот пример использования, который работает в JSFiddle:

jsonp("http://jsfiddle.net/echo/jsonp", {
    "hello": "world"
}, function (response) {
    alert(response.hello);
});

В этой реализации не рассматриваются некоторые другие проблемы, но она предотвращает весь доступ к DOM или текущему JavaScript на странице, можно создать безопасную среду WebWorker .

Это должно работать на IE10 +, Chrome, Firefox и Safari, а также на мобильных браузерах.