项目停止维护, 详见issue.
可编程通知器.
🍂 A programmable notifier.
Home Page: https://chrome.google.com/webstore/detail/cnelmenogjgobndnoddckekbojgginbn
License: MIT License
套件无效,详细资料:Name of a key "appdesc" is invalid. Only ASCII [a-z], [A-Z], [0-9] and "_" are allowed.。
https://keylol.com/forum.php?mod=redirect&goto=findpost&ptid=581003&pid=11267001
现时只有简中和英文才能使用此插件
希望能支援繁体中文CHROME
即使显示的是英文或是简中也没关系
只是不太想改动浏览器本身语言
Gloria是建立在Manifest V2之上的浏览器扩展程序, Manifest V2现已被Manifest V3替代, 最终会失去浏览器支持, 详见Chrome的Manifest V2支持时间表.
在尝试将Gloria从Manifest V2迁移至Manifest V3的过程中, 我们遇到了无法克服的障碍, 这导致迁移无法完成, 项目因此走向终结.
Manifest V3的Service Worker限制了执行动态代码的能力, 因此我们需要通过offscreen document来绕过限制.
在offscreen document里, 存在一个奇妙的例外允许执行动态代码, 尚不确定这是否属于安全漏洞.
借助这一例外, 仍然不足以运行预期中的Gloria脚本, 因为Worker无法导入外部模块(原本使用内置模块gloria-utils
的做法因为无法实现对依赖项的版本控制, 遭到废弃).
尝试1:
const script = `import { waitForTimeout } from 'https://esm.sh/@blackglory/[email protected]'`
const blob = new Blob([script], { type: 'application/javascript' })
const url = URL.createObjectURL(blob)
new Worker(url, { type: 'module' })
Refused to create a worker from 'https://esm.sh/@blackglory/[email protected]' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'worker-src' was not explicitly set, so 'script-src' is used as a fallback.
Refused to create a worker from 'https://esm.sh/@blackglory/[email protected]' because it violates the following Content Security Policy directive: "script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' http://localhost:* http://127.0.0.1:*". Note that 'worker-src' was not explicitly set, so 'script-src' is used as a fallback.
尝试2:
const script = `import('https://esm.sh/@blackglory/[email protected]')`
const blob = new Blob([script], { type: 'application/javascript' })
const url = URL.createObjectURL(blob)
new Worker(url, { type: 'module' })
Refused to create a worker from 'https://esm.sh/@blackglory/[email protected]' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'worker-src' was not explicitly set, so 'script-src' is used as a fallback.
Refused to create a worker from 'https://esm.sh/@blackglory/[email protected]' because it violates the following Content Security Policy directive: "script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' http://localhost:* http://127.0.0.1:*". Note that 'worker-src' was not explicitly set, so 'script-src' is used as a fallback.
尝试3:
import { javascript } from 'extra-tags'
const script = esm(`import { waitForTimeout } from 'https://esm.sh/@blackglory/[email protected]'`)
const blob = new Blob([script], { type: 'application/javascript' })
const url = URL.createObjectURL(blob)
new Worker(url)
function esm(code) {
return javascript`
loadESMScript(${code})
async function loadESMScript(script) {
const blob = new Blob([script], { type: 'application/javascript' })
const url = URL.createObjectURL(blob)
await import(url)
URL.revokeObjectURL(url)
}
`
}
Refused to load the script 'blob:chrome-extension://hjbedkekcmmaclhccpicpjbkbhjniblj/9fa8785b-5e3f-42fd-86df-7b845f443070' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
loadESMScript @ 321e052c-f1af-4bad-9d77-41d771f9e83e:6
321e052c-f1af-4bad-9d77-41d771f9e83e:6 Refused to load the script 'blob:chrome-extension://hjbedkekcmmaclhccpicpjbkbhjniblj/9fa8785b-5e3f-42fd-86df-7b845f443070' because it violates the following Content Security Policy directive: "script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' http://localhost:* http://127.0.0.1:*". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
尝试4:
import { javascript } from 'extra-tags'
const script = esm(`import('https://esm.sh/@blackglory/[email protected]')`)
const blob = new Blob([script], { type: 'application/javascript' })
const url = URL.createObjectURL(blob)
new Worker(url)
function esm(code) {
return javascript`
loadESMScript(${code})
async function loadESMScript(script) {
const blob = new Blob([script], { type: 'application/javascript' })
const url = URL.createObjectURL(blob)
await import(url)
URL.revokeObjectURL(url)
}
`
}
Refused to load the script 'blob:chrome-extension://hjbedkekcmmaclhccpicpjbkbhjniblj/e13f475e-4dbd-4dec-811e-cd417d0a37b5' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
loadESMScript @ 1b0b39d4-517b-42b2-af32-be06cf3be884:6
1b0b39d4-517b-42b2-af32-be06cf3be884:6 Refused to load the script 'blob:chrome-extension://hjbedkekcmmaclhccpicpjbkbhjniblj/e13f475e-4dbd-4dec-811e-cd417d0a37b5' because it violates the following Content Security Policy directive: "script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' http://localhost:* http://127.0.0.1:*". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
实测表明针对性修改CSP也没用.
尽管我们确实可以在Worker里正常访问外部资源:
fetch('https://blackglory.me')
.then(res => res.text())
.then(console.log)
但这只能满足最低限度的Gloria脚本用例.
例如, 你可能会需要JSDOM, 因为你需要DOMParser来解析HTML或XML(原生Web Workers环境里并不存在DOMParser).
总之, 直接在offscreen document里执行动态代码的做法并不怎么靠谱:
Manifest V3实际上也有正规的执行不安全代码的方法, 即从Manifest V2就有的基于iframe的沙盒.
对于Gloria的用例, 需要在offscreen document里创建和使用基于iframe的沙盒.
最初, 我对此方案很有信心, 毕竟官方已经给出了执行不安全代码的方法, 还能出什么错呢?
尝试1:
fetch('https://blackglory.me')
.then(res => res.text())
.then(console.log)
Access to fetch at 'https://blackglory.me/' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
原因在于iframe的origin是null
, 因此不具有扩展程序的跨域能力, 在manifest.json
里声明的host_permissions
对iframe来说没有任何意义.
理论上, 可以通过为iframe启用allow-same-origin
来使其获得与扩展程序相同的origin, 从而获得跨域能力.
尝试2:
const script = `import { waitForTimeout } from 'https://esm.sh/@blackglory/[email protected]'`
const blob = new Blob([script], { type: 'application/javascript' })
const url = URL.createObjectURL(blob)
new Worker(url, { type: 'module' })
Refused to cross-origin redirects of the top-level worker script.
尝试3:
const script = `import('https://esm.sh/@blackglory/[email protected]')`
const blob = new Blob([script], { type: 'application/javascript' })
const url = URL.createObjectURL(blob)
new Worker(url, { type: 'module' })
Refused to cross-origin redirects of the top-level worker script.
尝试4:
import { javascript } from 'extra-tags'
const script = esm(`import { waitForTimeout } from 'https://esm.sh/@blackglory/[email protected]'`)
const blob = new Blob([script], { type: 'application/javascript' })
const url = URL.createObjectURL(blob)
new Worker(url)
function esm(code) {
return javascript`
loadESMScript(${code})
async function loadESMScript(script) {
const blob = new Blob([script], { type: 'application/javascript' })
const url = URL.createObjectURL(blob)
await import(url)
URL.revokeObjectURL(url)
}
`
}
正常运行, 至少我们有一种方式可以导入带有CORS header的外部模块.
尝试在manifest.json
里添加allow-same-origin
来解决跨域问题:
"content_security_policy": {
"sandbox": "sandbox allow-scripts allow-same-origin;"
}
Invalid value for 'content_security_policy.sandbox'.
在HTML的iframe的sandbox属性上添加allow-same-origin
则会静默失败.
显然, Chrome有意阻止为Sandbox启用allow-same-origin
选项.
其中一个原因可能是同时启用allow-scripts
和allow-same-origin
能让沙盒内的代码逃逸.
至此我们陷入一个奇怪的局面:
一种解决方案是在offscreen document里向iframe暴露一个API, 使其能够访问任意外部资源.
这意味着对fetch
, EventSource
, WebSocket
这样的Web API进行包装.
此方案的实施难度大, 兼容性差, 其中一些数据类型很可能无法在上下文之间复制或转移, 不可行.
另一种解决方案是通过Manifest V3臭名昭著的DNR为响应添加CORS header, 从而绕过跨域限制.
然而, DNR的过滤条件无法匹配到由扩展程序沙盒发出的来自opaque origin的请求.
理想状态下, 这应该适用于沙盒, 可惜它没有:
chrome.declarativeNetRequest.updateDynamicRules({
removeRuleIds: [1]
, addRules: [
{
id: 1
, condition: {
initiatorDomains: [chrome.runtime.id]
}
, action: {
type: chrome.declarativeNetRequest.RuleActionType.MODIFY_HEADERS
, responseHeaders: [
{
operation: chrome.declarativeNetRequest.HeaderOperation.SET
, header: 'Access-Control-Allow-Origin'
, value: '*'
}
]
}
}
]
})
这适用于沙盒, 但影响了浏览器内的所有请求, 引入巨大的安全问题:
chrome.declarativeNetRequest.updateDynamicRules({
removeRuleIds: [1]
, addRules: [
{
id: 1
, condition: {}
, action: {
type: chrome.declarativeNetRequest.RuleActionType.MODIFY_HEADERS
, responseHeaders: [
{
operation: chrome.declarativeNetRequest.HeaderOperation.SET
, header: 'Access-Control-Allow-Origin'
, value: '*'
}
]
}
}
]
})
另一方面, 很难用DNR维持Gloria现有的Cookie
, Referer
, Origin
动态注入能力, 这破坏了Gloria订阅私人消息的用例.
我在Gloria上的大多数技术决策都受到开发Gloria时的时代局限, 在这方面我不认为有做错什么.
在开发Gloria时, JavaScript被CoffeeScript替代, 因此我选择用CoffeeScript的超集LiveScript来开发, ESM支持和ESM CDN不存在, 流行模块标准至少有三个, 大多数MVVM都被Angular带上了双向数据绑定的弯路, TypeScript则根本没几个人使用.
如今JavaScript已经发展到ES2023, 我们有了原生的ESM支持, 有像https://esm.sh这样的ESM CDN,
有React这样成熟的MVVM框架, 并且大多数仍被使用的npm模块要么用TypeScript重写, 要么具有TypeScript类型定义.
现有的Web技术是当年难以想象的, Gloria项目最失败的部分是没有跟上Web技术的步伐,
这都是因为我在开发Gloria时没有采用一个易于维护的架构.
当Gloria的代码逐渐变得陈旧, 任何大的改变都需要以重写的形式来实现时, 项目的发展理所当然地停滞了.
最终, 重写没有到来, 到来的是Manifest V3替代Manifest V2的历史车轮.
这是Gloria原本预定实装的新脚本格式, 对想要开发类似项目的开发者也许会有参考价值:
// -- 此脚本的各种元数据, 语法类似于油猴脚本 --
// @name 脚本显示的名称
// @update-url 脚本的更新地址
// -- 导入外部ESM模块 --
// -- 其他只在创建Worker时运行一次的代码 --
// -- 作为ESM模块的默认项返回, 执行器将会根据返回值类型决定是否采用轮询方式 --
export default function (signal: AbortSignal):
| INotification[]
| PromiseLike<INotification[]>
| Observable<INotification>
| AsyncIterable<INotification>
一旦我开始开发替代解决方案, 就不再可能会有转机, 因为我不能同时维护复数服务于相似目的的项目.
I am a userscript developer and submit My code in github.
我是一个在github提交代码的用户脚本开发者.
Can you add a feature to sync code from github on your website? like greasyfork.org
能否在你的网站上添加一个同步github代码的功能吗? 就像greasyfork.org
以这个任务为例 https://gloria.pub/task/64f38d0db7af1c0010ac0f73 代码还是有一些问题,但是测试的时候会一直弹出通知,试过 「清理所有 STAGES(一个用于缓存通知的内部组件)」、「清理所有 CACHES(一个用于缓存网络请求的内部组件)」也无济于事。
配合Reducer功能可以实现提醒的不间断推送
推送正常,但不会有弹窗
https://gloria.pub/task/57dc17da33fc01000f57accb
这个Github Trending today 无法使用了, 网页结构变了, 能更新一下脚本吗?
未来有对localStorage和indexedDB的支持吗
Hello,
your Task
https://gloria.pub/task/57af71d4af1728000fddef65
for Github don't work anymore
Can you fix this please
需要登录的那种。因为订阅太多用户,一个个添加太吃资源。要求会显示作者,视频也能有预览图,谢谢
有些监控页面是移动端的,所以 fetch 修改 ua 拿到页面数据,但是我修改后发现无效。
fetch(url,{ headers:{ 'user-agent': 'Mobile' } })
似乎是 Chrome 不支持修改 user-agent,https://bugs.chromium.org/p/chromium/issues/detail?id=571722
有办法绕过不?例如通过 node runtime ?
使用 Edge 浏览器,添加以下代码,并设置为1分钟, 打开 background
页的 F12 可以看到有定时执行,但是并不会弹出通知~
commit({ message: "hhhhhh", });
从前台的测试代码处执行会有通知
Edge版本 112.0.1722.58 (正式版本) (64 位)
我想要一个不同网站自动一键匹配关键字的..
类似SearchBar和Selection Search
Hi, I try to use Gloria to listen Baidu Tieba message.
你好, 我想要使用Gloria监听百度贴吧的消息.
(async () => {
const domain = 'http://tieba.baidu.com';
const {cheerio} = await importScripts('gloria-utils');
const html = await fetch(domain + '/f/like/mylike?pn=1').then(res => res.text());
const $ = cheerio.load(html);
return { title: '1', message: '2', url: '3', iconUrl: '4'}
})().then(commit);
In Background Page, I can not see cookie in Request Header.
在背景页, 我在请求头里看不到cookie
But in Brower Tab, I can see cookie in Request Header.
但是在浏览器标签页, 我能在请求头看到cookie.
Cookies are necessary to obtain private messages. what should I do?
为了获取私人消息, Cookie是必需的. 我应该怎么做呢?
Chrome Version: 81.0.4044.138
Gloria Version: 0.13.10
嘤嘤嘤...
最好可以支持多个词语单独探测...
https://rarbgprx.org/torrents.php
假如我创建了一个任务,间隔时间设定为 60 分钟。
在这 60 分钟内关闭再打开浏览器时,会发现任务在开启浏览器时又执行一次。也就是说这个任务并不是严格按照间隔器设定的时间进行检查的。
请问这是故意如此设计的还是我遇到了什么问题?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.