我只需要支持新的浏览器。
我必须依靠外部服务来提供 JSONP 数据,我不拥有该服务并且它不允许CORS。
不得不信任来自外部服务器的 JSONP 请求让我感到非常不安,因为它们可以在我端运行任意代码,这将允许它们跟踪我的用户,甚至窃取他们的信息。
我想知道是否有任何方法可以创建同样安全的 JSONP 请求?
(相关:如何可靠地保护公共 JSONP 请求?但不是新的浏览器放松)
注意:我问/回答了问答风格,但我对其他想法非常开放。
我只需要支持新的浏览器。
我必须依靠外部服务来提供 JSONP 数据,我不拥有该服务并且它不允许CORS。
不得不信任来自外部服务器的 JSONP 请求让我感到非常不安,因为它们可以在我端运行任意代码,这将允许它们跟踪我的用户,甚至窃取他们的信息。
我想知道是否有任何方法可以创建同样安全的 JSONP 请求?
(相关:如何可靠地保护公共 JSONP 请求?但不是新的浏览器放松)
注意:我问/回答了问答风格,但我对其他想法非常开放。
是的!
有可能的。一种方法是使用WebWorkers。在 WebWorkers 中运行的代码无法访问页面正在运行的 DOM 或其他 JavaScript 代码。
您可以创建一个 WebWorker 并使用它执行 JSONP 请求,然后在完成后终止它。
这个过程是这样的:
从带有要请求的 URL 的 blob 创建 WebWorker
用于importScripts
通过本地回调加载 JSONP 请求
当该回调执行时,将一条消息发送回脚本,然后脚本将使用数据执行实际的回调消息。
这样一来,攻击者就没有关于 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 以及移动浏览器。