dal*_*t97 5 html javascript browser web web-notifications
我想拦截HTML5 Web通知。我已经阅读了以下答案,其中用户建议可以window.Notification
用您自己的充当代理的对象覆盖该对象。我试图这样做,但是无法使其正常工作。以下是页面加载后我要注入的JavaScript代码:
function setNotificationCallback(callback) {
const OldNotify = window.Notification;
OldNotify.requestPermission();
const newNotify = (title, opt) => {
callback(title, opt);
return new OldNotify(title, opt);
};
newNotify.requestPermission = OldNotify.requestPermission.bind(OldNotify);
Object.defineProperty(newNotify, 'permission', {
get: () => {
return OldNotify.permission;
}
});
window.Notification = newNotify;
}
function notifyCallback(title, opt) {
console.log("title", title); // this never gets called
}
window.Notification.requestPermission(function (permission) {
if (permission === "granted") {
setNotificationCallback(notifyCallback);
}
})
Run Code Online (Sandbox Code Playgroud)
问题是箭头函数不能用作构造函数(Source)。
使用此代码的项目仍然具有箭头功能:https : //github.com/jiahaog/nativefier/blob/master/app/src/static/preload.js,但它在Electron中运行,这可能解释了为什么行为不同。
如果定位最新的浏览器,则应使用如下命名函数:
(function () {
function notifyCallback(title, opt) {
console.log("title", title);
}
const OldNotify = window.Notification;
function newNotify(title, opt) {
notifyCallback(title, opt);
return new OldNotify(title, opt);
}
newNotify.requestPermission = OldNotify.requestPermission.bind(OldNotify);
Object.defineProperty(newNotify, 'permission', {
get: () => {
return OldNotify.permission;
}
});
window.Notification = newNotify;
})();
Notification.requestPermission(function (permission) {
if (permission === "granted") {
const notif = new Notification('My title');
}
});
Run Code Online (Sandbox Code Playgroud)
这样创建的代理将在其他代码/库调用时有效,new Notification()
例如在我的示例中。我已将代理逻辑移到了顶层,以确保Notification
在用户接受接收通知之前,其他代码/库不会在本机上保留引用。您还必须将代码放在首位以确保这一点。
而且,如果您的目标浏览器支持ECMAScript 6,则有一种更为优雅的方法:
(function () {
function notifyCallback(title, opt) {
console.log("title", title);
}
const handler = {
construct(target, args) {
notifyCallback(...args);
return new target(...args);
}
};
const ProxifiedNotification= new Proxy(Notification, handler);
window.Notification = ProxifiedNotification;
})();
Notification.requestPermission(function (permission) {
if (permission === "granted") {
const notif = new Notification('My title');
}
});
Run Code Online (Sandbox Code Playgroud)
它具有更大的可扩展性(Notification
API在将来的ECMAScript版本中更改时不会产生影响,因为它允许操作本机Notification
而不是手工的)。
归档时间: |
|
查看次数: |
287 次 |
最近记录: |