windows.open()异步任务被浏览器拦截 / 任务出错
错误情况
最近帮朋友实现批量下载知网 pdf 论文的时候遇到了一个问题:
- 利用油猴脚本实现批量下载时,知网会拦截下载操作并报错 来源应用不正确2 。
- 但是脚本提取出的单个论文的 pdf 下载链接却可以直接通过点击链接单个下载。
原理解析
经过查阅脚本代码,分析两种方式的代码实现。
点击单个下载链接
代码实现了一个下载链接,用户点击这个单个论文的下载链接可以实现 pdf 下载。
通过脚本批量下载
可见为了规避知网的一些机器人屏蔽,采取了 async function
定义了一个异步处理函数。
async function
是 JavaScript 中用于定义异步函数的关键字。 异步函数是一种特殊的函数,它允许你使用await
关键字暂停函数的执行,等待一个 Promise 对象 resolve 或 reject,然后再继续执行。 这使得异步代码的编写和阅读更加容易,避免了回调地狱。
在异步函数中使用 window.open(link.href, '_blank')
实现下载单个文献。
原因分析
比较两种下载方式,可见成功的方式是直接点击 <a>
标签,失败的方式是 JS 脚本里的 windows.open()
。
现今的浏览器为了安全性会对很多非用户操作进行拦截,尤其是异步的任务。
在异步任务中使用函数 window.open()
极易让浏览器判定为是非用户直接操作,从而拦截打开的页面。
解决方案(一定程度上)
为了防止被浏览器判定是机器操作而非是用户直接操作,我们在异步函数中也仍然采取点击 <a>
标签的方式来进行下载:
通过 link.click()
来模拟用户直接点击下载链接。
对相关代码段进行如下替换即可:
再次测试,成功实现自动化批量下载文献。