本帖最后由 Endurance 于 2025-3-10 09:38 编辑
之前一只在使用一款RSS阅读器,fluent-reader(github地址:https://github.com/yang991178/fluent-reader),是使用过的阅读器中最优雅,也是最美观的,还能自定义过滤器,只关注自己关注的文章。原来一直从IEEE网站抓取RSS,直到去年IEEE网站更新之后就无法抓取了,阅读器报错http418。
源地址例子如下:https://ieeexplore.ieee.org/rss/TOC6720217.XML
本来觉得算了,不能用就不用了呗,但是后来还是觉得那样不方便看文章,又因为是开源的,于是就萌生出自己修改的想法。
下载下来源码之后,发现是Node.js和Electron框架编写的。
先编译一下,运行试试看。
先安装依赖库,npm install
然后编译: npm run build
然后运行:npm run electron
果然报错,http418,
看了看响应数据:
框架发送的标头是这样的:
用浏览器直接打开源地址,标头是这样的:
这样一对比,发现最关键的是”Sec-“的几个header造成的,那就改吧!在开发者工具那里点击”启动器“,发现是utils.ts文件中parseRSS方法出错了。
打开这个文件,定位到出错的方法部分:
[JavaScript] 纯文本查看 复制代码 export async function parseRSS(url: string) {
let result: Response
try {
result = await fetch(url, { credentials: "omit" })
} catch {
throw new Error(intl.get("log.networkError"))
}
if (result && result.ok) {
try {
return await rssParser.parseString(
await decodeFetchResponse(result)
)
} catch {
throw new Error(intl.get("log.parseError"))
}
} else {
throw new Error(result.status + " " + result.statusText)
}
}
这个简单,添加一个”User-Agent“和”Sec-*“的header不就可以了吗!动手修改之后,重新编译运行,发现还是报错,而且这两个字段居然没有修改成功!
这是怎么回事?开始上网查资料。原来是”跨域“造成的结果。https://juejin.cn/post/7064127816404566053
真是奇怪,我只是简单GET一个xml文件,怎么就跨域了?按照上面网页说的方法,修改fetch()方法中,添加mode: "no-cors"和cookies。修改完之后还是不行。这又是为啥呢?
想来想去想不明白,而且以前没接触过Node.js和Electron,这可咋办?
又问AI小助手,又查资料一顿折腾。查到在创建BrowserWindow的时候可以设置webPreferences参数中webSecurity为false,降低安全性换取不检查跨域。
[JavaScript] 纯文本查看 复制代码 webPreferences: {
webviewTag: true,
contextIsolation: true,
spellcheck: false,
webSecurity: false,
preload: path.join(
app.getAppPath(),
(app.isPackaged ? "dist/" : "") + "preload.js"
),
},
结果,还是不行。后来我就想,如果服务端只用这个”Sec-*"开头的header内容,那我是不是可以强行修改呢?Electron框架内是不能改的,因为是硬性规定。但是框架外呢?
通过这篇知乎专栏的文章,https://zhuanlan.zhihu.com/p/443998585
我试着把发送报文的header覆盖,我找到了创建BrowserWindow的文件是\\src\main\window.ts,于是在this.mainWindow = new BrowserWindow()方法之后加了一段内容:
[JavaScript] 纯文本查看 复制代码 this.mainWindow.webContents.session.webRequest.onBeforeSendHeaders(
(details, callback) => {
callback({ requestHeaders: {
'Origin': '*',
'sec-fetch-site': 'none',
'User-Agent': 'Teapot'
//...details.requestHeaders
}
});
},
);
强行覆盖header,重新编译,运行,结果成功了。
甚至我的User-Agent是Teapot都能成功:
至此,问题解决了。然后打包成Exe,问题完美解决。
|