您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
修复inoreader的图片加载问题
// ==UserScript== // @name fix-image-error at inoreader // @name:zh-CN 修复inoreader图片异常 // @version 0.5.0 // @namespace https://github.com/mengtao-code // @description Fix image load error caused by CSP(Content Security Policy) // @description:zh-CN 修复inoreader的图片加载问题 // @author Mengtao Xin // @license MIT // @supportURL https://github.com/mengtao-code/tampermonkey-scripts // @include http*://*.inoreader.com/* // @icon http://www.inoreader.com/favicon.ico // @grant GM_xmlhttpRequest // @connect * // ==/UserScript== const LOADING_PROMPT = 'Loading...' const config = { name: 'fix-image-error', data: [ // weibo images prefix { imageServer: 'sinaimg.cn', mockHeader: { Referer: 'https://weibo.com' } } ] } /** * * @link https://stackoverflow.com/questions/8778863/downloading-an-image-using-xmlhttprequest-in-a-userscript * @param {string} input * @returns {string} */ function toBase64(input) { var bbLen = 3, enCharLen = 4, inpLen = input.length, inx = 0, jnx, keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' + '0123456789+/=', output = '', paddingBytes = 0 var bytebuffer = new Array(bbLen), encodedCharIndexes = new Array(enCharLen) while (inx < inpLen) { for (jnx = 0; jnx < bbLen; ++jnx) { if (inx < inpLen) bytebuffer[jnx] = input.charCodeAt(inx++) & 0xff else bytebuffer[jnx] = 0 } encodedCharIndexes[0] = bytebuffer[0] >> 2 encodedCharIndexes[1] = ((bytebuffer[0] & 0x3) << 4) | (bytebuffer[1] >> 4) encodedCharIndexes[2] = ((bytebuffer[1] & 0x0f) << 2) | (bytebuffer[2] >> 6) encodedCharIndexes[3] = bytebuffer[2] & 0x3f paddingBytes = inx - (inpLen - 1) switch (paddingBytes) { case 1: // Set last character to padding char encodedCharIndexes[3] = 64 break case 2: // Set last 2 characters to padding char encodedCharIndexes[3] = 64 encodedCharIndexes[2] = 64 break default: break // No padding - proceed } for (jnx = 0; jnx < enCharLen; ++jnx) output += keyStr.charAt(encodedCharIndexes[jnx]) } return output } /** * * @param responseData data from http request * @returns {string} */ const getImageUrl = responseData => { const binResp = toBase64(responseData.responseText) return `data:image/jpeg;base64,${binResp}` } /** * send get http request * @param {string}url * @param customHeader * @returns {Promise<unknown>} */ const httpGetRequest = (url, customHeader) => { return new Promise((resolve, reject) => { GM.xmlHttpRequest({ method: 'GET', url: url, headers: { Accept: '*/*', referrerPolicy: 'no-referrer', ...customHeader }, onload: resolve, onerror: reject, overrideMimeType: 'text/plain; charset=x-user-defined' }) }) } /** * * @param {Element} dom * @param {*} mockHeader */ const processDetailImage = (dom, mockHeader) => { if (dom.getAttribute('process-tag') !== 'doing' && dom.getAttribute('process-tag') !== 'done') { dom.setAttribute('process-tag', 'doing') dom.setAttribute('alt', LOADING_PROMPT) const originUrl = dom.getAttribute('src') httpGetRequest(originUrl, mockHeader) .then(responseData => { const goodUrl = getImageUrl(responseData) dom.setAttribute('src', goodUrl) }) .catch(e => console.error(`${config.name} load image failed! ${e}`)) .finally(() => dom.setAttribute('process-tag', 'done')) } } const processListImage = (dom, mockHeader) => { if (dom.getAttribute('process-tag') !== 'doing' && dom.getAttribute('process-tag') !== 'done') { dom.setAttribute('process-tag', 'doing') const style = dom.getAttribute('style') const originUrl = style.substring(style.indexOf('https')).replace("')", '') console.log(`originUrl:${originUrl}`) httpGetRequest(originUrl, mockHeader) .then(responseData => { const goodUrl = getImageUrl(responseData) dom.setAttribute('style', `background-image:url('${goodUrl}')`) }) .catch(e => console.error(`${config.name} load image failed! ${e}`)) .finally(() => dom.setAttribute('process-tag', 'done')) } } /** * 检测到有异常图片,就调整成正常的图片 */ const main = () => { config.data.forEach(({ imageServer, mockHeader }) => { // 1. detail pages Array.from(document.querySelectorAll(`.article_content img[src*='${imageServer}']`)).forEach(image => processDetailImage(image, mockHeader)) // 2. list pages Array.from(document.querySelectorAll(`.article_magazine_picture, .article_tile_picture`)) .filter(dom => dom.getAttribute('style').includes(imageServer)) .forEach(image => processListImage(image, mockHeader)) }) } setInterval(main, 3000)
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址