├── .gitignore ├── README.md ├── images └── logo.png ├── jsconfig.json ├── manifest.json └── src ├── background.js ├── popup.html └── popup.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.zip 2 | temp/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 解除東立電子書城区域限制 2 | 3 | [![GitHub release](https://img.shields.io/github/release/ipcjs/tongli-ebook-tw-unblock.svg)](https://github.com/ipcjs/tongli-ebook-tw-unblock/releases/latest) 4 | [![Chrome Web Store](https://img.shields.io/chrome-web-store/v/afioeikjnpkbakbaejlgklolijejbcjh.svg)](https://chrome.google.com/webstore/detail/tongli-ebook-unblock/afioeikjnpkbakbaejlgklolijejbcjh) 5 | [![Chrome Web Store Users](https://img.shields.io/chrome-web-store/users/afioeikjnpkbakbaejlgklolijejbcjh.svg)](https://chrome.google.com/webstore/detail/tongli-ebook-unblock/afioeikjnpkbakbaejlgklolijejbcjh) 6 | 7 | **已失效** 8 | -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipcjs/tongli-ebook-tw-unblock/42d6b289929a507a3cc4cd57c31bf7f6adcccbbe/images/logo.png -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "typeAcquisition": { 3 | "include": [ 4 | "chrome" 5 | ] 6 | } 7 | } -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Tongli Ebook Unblock", 3 | "description": "解除東立電子書城区域限制", 4 | "version": "0.0.3", 5 | "manifest_version": 2, 6 | "background": { 7 | "scripts": [ 8 | "src/background.js" 9 | ], 10 | "persistent": true 11 | }, 12 | "permissions": [ 13 | "webRequest", 14 | "activeTab", 15 | "downloads", 16 | "webRequestBlocking", 17 | "*://ebook.tongli.com.tw/*", 18 | "https://*.azurewebsites.net/" 19 | ], 20 | "browser_action": { 21 | "default_popup": "src/popup.html", 22 | "default_icon": "images/logo.png" 23 | } 24 | } -------------------------------------------------------------------------------- /src/background.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | chrome.webRequest.onBeforeSendHeaders.addListener( 4 | (details) => { 5 | details.requestHeaders.push({ 6 | name: 'X-Forwarded-For', 7 | value: '59.125.39.5', 8 | }) 9 | return { requestHeaders: details.requestHeaders } 10 | }, 11 | { urls: ["*://ebook.tongli.com.tw/*"] }, 12 | ["blocking", 'requestHeaders'] 13 | ) -------------------------------------------------------------------------------- /src/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 17 | 18 |

19 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/popup.js: -------------------------------------------------------------------------------- 1 | function getCurrentTab() { 2 | return new Promise((resolve, reject) => { 3 | chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { 4 | resolve(tabs[0]) 5 | }) 6 | }) 7 | } 8 | 9 | function copyText(textarea, text) { 10 | if (text != undefined) { 11 | textarea.value = text 12 | } 13 | textarea.select() 14 | try { 15 | return document.execCommand('copy') 16 | } catch (e) { 17 | console.error('复制文本出错', e) 18 | } 19 | return false 20 | } 21 | 22 | function obtainAuthInContentScript() { 23 | function obtainAuthInPage() { 24 | console.log('obtainAuthInPage()', window.$, window.domain) 25 | window.postMessage({ 26 | type: 'teu:auth-info', 27 | content: { 28 | auth: window.$ && window.$.ajaxSettings.headers.Authorization, 29 | domain: window.domain 30 | } 31 | }, "*") 32 | } 33 | 34 | console.log('obtainAuthInContentScript()', window.$, window.domain) 35 | window.addEventListener('message', (event) => { 36 | if (typeof event.data.type === 'string' && event.data.type.startsWith('teu:')) { 37 | chrome.runtime.sendMessage(event.data) 38 | } 39 | }, { once: true }) 40 | let $script = document.createElement('script') 41 | $script.innerHTML = `${obtainAuthInPage.toString()}; ${obtainAuthInPage.name}();` 42 | document.body.appendChild($script) 43 | } 44 | 45 | const TAB_MSG_LISTENERS = new Map() 46 | chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { 47 | if (sender.tab) { 48 | let listener = TAB_MSG_LISTENERS.get(sender.tab.id) 49 | listener && listener(msg, sender, sendResponse) 50 | } 51 | }) 52 | 53 | function getAuth(tabId) { 54 | return new Promise((resolve, reject) => { 55 | TAB_MSG_LISTENERS.set(tabId, (msg, sender, sendResponse) => { 56 | if (msg.type === 'teu:auth-info') { 57 | resolve(msg.content) 58 | TAB_MSG_LISTENERS.delete(tabId) 59 | } 60 | }) 61 | chrome.tabs.executeScript(tabId, { code: `${obtainAuthInContentScript.toString()}; ${obtainAuthInContentScript.name}();` }) 62 | }) 63 | } 64 | 65 | async function main() { 66 | let $msg = document.getElementById('msg') 67 | let $output = document.getElementById('output') 68 | let $result = document.getElementById('result') 69 | $result.style.display = 'none' 70 | let tab = await getCurrentTab() 71 | let url = new URL(tab.url) 72 | if (url.host === 'ebook.tongli.com.tw' && url.searchParams.has('bookID')) { 73 | $msg.innerText = '获取Authorization中...' 74 | let { auth, domain } = await getAuth(tab.id) 75 | if (auth && domain) { 76 | $msg.innerText = '获取下载地址中...' 77 | let result = await fetch(`${domain}/Comic/${url.searchParams.get('bookID')}`, { headers: { Authorization: auth } }) 78 | .then(r => r.json()) 79 | .catch(e => { 80 | $msg.innerText = '获取下载地址失败, 请刷新页面重试' 81 | }) 82 | if (result) { 83 | console.log('result', result) 84 | $msg.innerHTML = '结果:' 85 | $result.style.display = '' 86 | 87 | Array.from($result.querySelectorAll('input[type=button]')).forEach(it => { 88 | it.addEventListener('click', (event) => { 89 | switch (event.target.name) { 90 | case 'copy-curl': 91 | copyText($output, result.Pages.map(it => `curl '${it.ImageURL}' -H 'Authorization: ${auth}' -o ${it.PageNumber}.jpg`).join('\n') + '\n') 92 | break 93 | case 'copy-yaaw': 94 | copyText($output, `Authorization: ${auth}\n\n\n${result.Pages.map(it => `${it.ImageURL} --out=${it.PageNumber}.jpg`).join('\n')}`) 95 | break 96 | case 'copy': 97 | copyText($output) 98 | break 99 | case 'download': 100 | result.Pages.forEach(page => { 101 | chrome.downloads.download({ 102 | url: page.ImageURL, 103 | conflictAction: 'overwrite', 104 | filename: `${result.Title}/${page.PageNumber}.jpg`, 105 | headers: [ 106 | { name: 'Authorization', value: auth } 107 | ] 108 | }) 109 | }) 110 | break 111 | } 112 | }) 113 | }) 114 | 115 | $output.value = result.Pages.map(it => it.ImageURL).join('\n') 116 | } 117 | } else { 118 | $msg.innerText = '获取Authorization失败, 请重试' 119 | } 120 | } else { 121 | $msg.innerText = '未检测到漫画下载地址' 122 | } 123 | } 124 | 125 | main() --------------------------------------------------------------------------------