您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
从 itms-services 链接中提取 IPA 下载直链或显示错误提示,并显示在原始按钮旁边
当前为
- // ==UserScript==
- // @name iOS App Download Link Extractor
- // @namespace https://github.com/WangONC/ios-app-download-link-extractor
- // @version 0.9.0
- // @description Extracts the IPA download link from itms-services URLs or displays an error message, shown next to the original button.
- // @author WangONC
- // @source https://github.com/WangONC/ios-app-download-link-extractor
- // @match *://*/*
- // @grant GM.xmlHttpRequest
- // @license MIT
- // @name:en iOS App Download Link Extractor
- // @description:en Extracts the IPA download link from itms-services URLs or displays an error message, shown next to the original button.
- // @name:zh-CN IPA提取助手
- // @description:zh-CN 从 itms-services 链接中提取 IPA 下载直链或显示错误提示,并显示在原始按钮旁边
- // @name:zh-TW IPA提取助手
- // @description:zh-TW 從 itms-services 連結中提取 IPA 下載直鍊或顯示錯誤提示,並顯示在原始按鈕旁邊
- // @name:ar مُستخرج رابط تنزيل تطبيقات iOS
- // @description:ar يستخرج رابط تنزيل IPA من عناوين itms-services أو يعرض رسالة خطأ، تُظهر بجانب الزر الأصلي
- // @name:bg Екстрактор на връзки за изтегляне на iOS приложения
- // @description:bg Извлича връзката за изтегляне на IPA от itms-services URL-и или показва съобщение за грешка до оригиналния бутон
- // @name:ckb دەرهێنەری بەستەری داگرتنی ئەپی iOS
- // @description:ckb بەستەری داگرتنی IPA لە itms-services URLەکان دەرهێنەرە یان پەیامی هەڵە نیشان دەدات، کە لە تەنیشتی دوگمەی سەرەکی دەردەکەوێت
- // @name:cs Extraktor odkazů ke stažení aplikací pro iOS
- // @description:cs Extrahuje odkaz na stažení IPA z adres itms-services nebo zobrazí chybovou zprávu vedle původního tlačítka
- // @name:da iOS App Download Link Extractor
- // @description:da Uddrager IPA-downloadlinket fra itms-services URL'er eller viser en fejlmeddelelse ved siden af den originale knap
- // @name:de iOS App Download Link Extractor
- // @description:de Extrahiert den IPA-Download-Link aus itms-services URLs oder zeigt eine Fehlermeldung neben dem ursprünglichen Button an
- // @name:el Εξαγωγέας Συνδέσμων Λήψης Εφαρμογών iOS
- // @description:el Εξάγει τον σύνδεσμο λήψης IPA από URLs itms-services ή εμφανίζει ένα μήνυμα σφάλματος δίπλα στο αρχικό κουμπί
- // @name:eo Eltiraĵo de Elŝuta Ligilo por iOS-Aplikoj
- // @description:eo Eltiras la IPA-elŝutan ligilon el itms-services URL-oj aŭ montras erarmesaĝon apud la originala butono
- // @name:es Extractor de Enlaces de Descarga de Aplicaciones iOS
- // @description:es Extrae el enlace de descarga de IPA de las URLs de itms-services o muestra un mensaje de error junto al botón original
- // @name:es-419 Extractor de Enlaces de Descarga de Aplicaciones iOS
- // @description:es-419 Extrae el enlace de descarga de IPA de las URLs de itms-services o muestra un mensaje de error junto al botón original
- // @name:fi iOS-sovelluksen latauslinkin poimija
- // @description:fi Puraisee IPA-latauslinkin itms-services-URL-osoitteista tai näyttää virheilmoituksen alkuperäisen painikkeen vieressä
- // @name:fr Extracteur de liens de téléchargement d'applications iOS
- // @description:fr Extrait le lien de téléchargement IPA des URL itms-services ou affiche un message d'erreur à côté du bouton d'origine
- // @name:fr-CA Extracteur de liens de téléchargement d'applications iOS
- // @description:fr-CA Extrait le lien de téléchargement IPA des URL itms-services ou affiche un message d'erreur à côté du bouton d'origine
- // @name:he מחלץ קישורי הורדה לאפליקציות iOS
- // @description:he מחלץ את קישור ההורדה של IPA מכתובות itms-services או מציג הודעת שגיאה ליד הכפתור המקורי
- // @name:hr Izvlači poveznice za preuzimanje iOS aplikacija
- // @description:hr Izvlači poveznicu za preuzimanje IPA iz itms-services URL-ova ili prikazuje poruku o grešci pored originalnog gumba
- // @name:hu iOS App Letöltési Link Kivonó
- // @description:hu Kinyeri az IPA letöltési linket az itms-services URL-ekből vagy hibaüzenetet jelenít meg az eredeti gomb mellett
- // @name:id Pengekstrak Tautan Unduhan Aplikasi iOS
- // @description:id Mengekstrak tautan unduhan IPA dari URL itms-services atau menampilkan pesan kesalahan di samping tombol asli
- // @name:it Estrattore di Link di Download per App iOS
- // @description:it Estrae il link di download IPA dagli URL itms-services o visualizza un messaggio di errore accanto al pulsante originale
- // @name:ja iOSアプリダウンロードリンク抽出ツール
- // @description:ja itms-services URLからIPAダウンロードリンクを抽出するか、エラーメッセージを元のボタンの横に表示します
- // @name:ka iOS აპლიკაციის ჩამოტვირთვის ბმულის ამომღები
- // @description:ka ამოიღებს IPA-ს ჩამოტვირთვის ბმულს itms-services URL-ებიდან ან აჩვენებს შეცდომის შეტყობინებას ორიგინალური ღილაკის გვერდით
- // @name:ko iOS 앱 다운로드 링크 추출기
- // @description:ko itms-services URL에서 IPA 다운로드 링크를 추출하거나 오류 메시지를 원래 버튼 옆에 표시합니다
- // @name:mr iOS अॅप डाउनलोड लिंक एक्स्ट्रॅक्टर
- // @description:mr itms-services URL मधून IPA डाउनलोड लिंक काढून किंवा त्रुटी संदेश दाखवून, मूळ बटणाजवळ दर्शविलेला
- // @name:nb iOS App Nedlastingslenke Ekstraktor
- // @description:nb Trekker ut IPA-nedlastingslenken fra itms-services URL-er eller viser en feilmelding ved siden av den opprinnelige knappen
- // @name:nl iOS App Download Link Extractor
- // @description:nl Extraheert de IPA-downloadlink van itms-services URL's of toont een foutmelding naast de originele knop
- // @name:pl Ekstraktor linków do pobierania aplikacji iOS
- // @description:pl Wyciąga link do pobrania IPA z adresów URL itms-services lub wyświetla komunikat o błędzie obok oryginalnego przycisku
- // @name:pt Extrator de Link de Download de Aplicativos iOS
- // @description:pt Extrai o link de download do IPA de URLs itms-services ou exibe uma mensagem de erro ao lado do botão original
- // @name:pt-BR Extrator de Link de Download de Aplicativos iOS
- // @description:pt-BR Extrai o link de download do IPA de URLs itms-services ou exibe uma mensagem de erro ao lado do botão original
- // @name:ro Extragător de Linkuri de Descărcare pentru Aplicații iOS
- // @description:ro Extrage linkul de descărcare IPA din URL-urile itms-services sau afișează un mesaj de eroare lângă butonul original
- // @name:ru Экстрактор ссылок на скачивание приложений iOS
- // @description:ru Извлекает ссылку на скачивание IPA из URL-адресов itms-services или отображает сообщение об ошибке рядом с оригинальной кнопкой
- // @name:sk Extraktor odkazov na stiahnutie aplikácií pre iOS
- // @description:sk Extrahuje odkaz na stiahnutie IPA z adries itms-services alebo zobrazí chybovú správu vedľa pôvodného tlačidla
- // @name:sr Екстрактор веза за преузимање iOS апликација
- // @description:sr Екстрахује везу за преузимање IPA из itms-services URL-ова или приказује поруку о грешци поред оригиналног дугмета
- // @name:sv iOS App Nedladdningslänk Extraktor
- // @description:sv Extraherar IPA-nedladdningslänken från itms-services URL:er eller visar ett felmeddelande bredvid den ursprungliga knappen
- // @name:th ตัวดึงลิงค์ดาวน์โหลดแอป iOS
- // @description:th ดึงลิงค์ดาวน์โหลด IPA จาก URL itms-services หรือแสดงข้อความผิดพลาดข้างปุ่มต้นฉบับ
- // @name:tr iOS Uygulama İndirme Bağlantısı Çıkarıcı
- // @description:tr itms-services URL'lerinden IPA indirme bağlantısını çıkarır veya orijinal butonun yanında bir hata mesajı gösterir
- // @name:uk Екстрактор посилань для завантаження додатків iOS
- // @description:uk Витягує посилання на завантаження IPA з URL-адрес itms-services або відображає повідомлення про помилку поруч з оригінальною кнопкою
- // @name:ug iOS ئەپ تۆۋەنلىك ئۇلىنىشىنى چىقىرىش
- // @description:ug itms-services URL لىرىدىن IPA چۈشۈرۈش ئۇلىنىشىنى چىقىرىپ ياكى ئەسلى كۇنۇپكا يېنىدا خاتالىق ئۇچۇرىنى كۆرسىتىدۇ
- // @name:vi Trích xuất liên kết tải xuống ứng dụng iOS
- // @description:vi Trích xuất liên kết tải IPA từ URL itms-services hoặc hiển thị thông báo lỗi bên cạnh nút gốc
- // ==/UserScript==
- (function() {
- 'use strict';
- const MAX_RETRIES = 3; // 最大重试次数
- const RETRY_INTERVAL = 1000; // 重试间隔
- const TIMEOUT = 500; // 超时时间
- function fetchPlist(plistUrl, retryCount, link) {
- GM.xmlHttpRequest({
- method: 'GET',
- url: plistUrl,
- timeout: TIMEOUT, // 设置超时时间
- onload: function(response) {
- if (response.status === 200) {
- let xmlText = response.responseText;
- let parser = new DOMParser();
- let xmlDoc = parser.parseFromString(xmlText, 'text/xml');
- let downloadUrl = extractDownloadUrl(xmlDoc);
- if (downloadUrl) {
- let downloadLink = document.createElement('a');
- downloadLink.href = downloadUrl;
- downloadLink.target = '_blank'; // 新窗口打开,方便下载
- downloadLink.textContent = 'Download IPA';
- downloadLink.style.marginLeft = '13px';
- downloadLink.classList.add('ipa-download-link'); // 添加类名以便识别
- link.insertAdjacentElement('afterend', downloadLink);
- } else {
- showError(link, 'Unable to parse plist file');
- }
- } else {
- showError(link, `Request failed: ${response.status}`);
- }
- },
- onerror: function() {
- if (retryCount > 0) {
- setTimeout(() => {
- fetchPlist(plistUrl, retryCount - 1, link); // 递归重试
- console.log(`当前重试 ${retryCount - 1}`);
- }, RETRY_INTERVAL);
- } else {
- showError(link, 'Network Error');
- }
- },
- ontimeout: function() {
- if (retryCount > 0) {
- setTimeout(() => {
- fetchPlist(plistUrl, retryCount - 1, link);
- console.log(`当前重试 ${retryCount - 1}`);
- }, RETRY_INTERVAL);
- } else {
- showError(link, 'Request timed out');
- }
- }
- });
- }
- // 处理页面中的链接
- function processLinks() {
- let links = document.querySelectorAll('a[href^="itms-services://?action=download-manifest&url="]');
- if (links.length === 0) {
- // console.log('No matching links found');
- return;
- }
- for (let link of links) {
- // 检查新添加的链接
- if (link.nextElementSibling && (link.nextElementSibling.classList.contains('ipa-download-link') || link.nextElementSibling.classList.contains('ipa-error-link'))) {
- continue;
- }
- // 检查是否是已经处理过的链接
- if (link.getAttribute('ipa-data-processed') === 'true') {
- continue;
- }
- // 标记该链接为已处理
- link.setAttribute('ipa-data-processed', 'true');
- try {
- let href = link.href;
- let query = href.split('?')[1];
- if (!query) throw new Error('Invalid link format');
- let params = new URLSearchParams(query);
- let plistUrl = params.get('url');
- if (!plistUrl) throw new Error('No "url" parameter found');
- // 解码 plistUrl 以处理 URL 编码
- plistUrl = decodeURIComponent(plistUrl);
- fetchPlist(plistUrl, MAX_RETRIES, link);
- } catch (e) {
- showError(link, e.message);
- }
- }
- }
- // 提取下载链接的核心函数
- function extractDownloadUrl(xmlDoc) {
- let dict = xmlDoc.querySelector('plist > dict');
- if (!dict) return null;
- let keys = Array.from(dict.children).filter(el => el.tagName === 'key');
- let itemsKey = keys.find(key => key.textContent === 'items');
- if (!itemsKey) return null;
- let itemsArray = itemsKey.nextElementSibling;
- if (!itemsArray || itemsArray.tagName !== 'array') return null;
- let firstItem = itemsArray.querySelector('dict');
- if (!firstItem) return null;
- let assetsKey = Array.from(firstItem.children).find(el => el.tagName === 'key' && el.textContent === 'assets');
- if (!assetsKey) return null;
- let assetsArray = assetsKey.nextElementSibling;
- if (!assetsArray || assetsArray.tagName !== 'array') return null;
- let softwarePackageDict = Array.from(assetsArray.children).find(dict => {
- let kindKey = Array.from(dict.children).find(key => key.tagName === 'key' && key.textContent === 'kind');
- if (kindKey && kindKey.nextElementSibling.textContent === 'software-package') {
- return true;
- }
- return false;
- });
- if (!softwarePackageDict) return null;
- let urlKey = Array.from(softwarePackageDict.children).find(el => el.tagName === 'key' && el.textContent === 'url');
- if (!urlKey) return null;
- return urlKey.nextElementSibling.textContent;
- }
- // 显示错误提示的函数
- function showError(link, message) {
- let errorLink = document.createElement('a');
- errorLink.textContent = message;
- errorLink.style.color = 'red';
- errorLink.style.marginLeft = '13px';
- errorLink.style.pointerEvents = 'none'; // 防止点击
- errorLink.classList.add('ipa-error-link'); // 添加类名以便识别
- link.insertAdjacentElement('afterend', errorLink);
- }
- document.addEventListener('DOMContentLoaded', function() {
- processLinks();
- });
- window.addEventListener('load', function() {
- processLinks();
- });
- // 监听动态内容加载
- const observer = new MutationObserver(() => {
- processLinks();
- });
- observer.observe(document.body, { childList: true, subtree: true, attributes: true });
- })();