2013-05-21 27 views
6

我只需要支持new browsers是否可以创建一个安全的JSONP请求?

我必须依靠外部服务来提供JSONP数据,我不拥有该服务,它不允许CORS

我不得不信任来自外部服务器的JSONP请求,因为他们可以在我的端运行任意代码,这将允许他们跟踪我的用户,甚至窃取他们的信息。

我想知道是否有任何方法来创建一个也是安全的JSONP请求?

(相关:How to reliably secure public JSONP requests?但不能与新的浏览器松弛)

注:我问/回答。问&一种风格,但我对其他的想法很开放。

回答

11

是的!

这是可能的。一种方法是使用WebWorkers。在WebWorkers中运行的代码无法访问您的页面正在运行的DOM或其​​他JavaScript代码。

您可以创建WebWorker并使用它执行JSONP请求,然后在完成后终止它。

的过程是这样的:

  • 从与URL斑点创建WebWorker要求

  • 使用importScripts与当地的回调

  • 加载JSONP请求当该回调执行时,将消息发送回脚本,该脚本又将执行实际回调消息和数据。

这样,攻击者就没有关于DOM的信息。

这里是一个sample implementation

// 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,可以创建safe WebWorker environment

这应该适用于IE10 +,Chrome,Firefox和Safari以及移动浏览器。

相关问题