Get Real Download URL

Get the real download URL by right-clicking on a download link while holding the left Alt key.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Get Real Download URL
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Get the real download URL by right-clicking on a download link while holding the left Alt key.
// @match        *://*/*
// @grant        GM_setClipboard
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    document.addEventListener('contextmenu', function(event) {
        if (event.altKey) {
            const link = event.target.closest('a[href]');
            if (link) {
                // Create the custom menu item as a floating button
                const customMenuItem = document.createElement('div');
                customMenuItem.textContent = 'Get Real Download URL';
                customMenuItem.style.position = 'fixed';
                customMenuItem.style.backgroundColor = '#fff';
                customMenuItem.style.border = '1px solid #ccc';
                customMenuItem.style.padding = '5px';
                customMenuItem.style.cursor = 'pointer';
                customMenuItem.style.zIndex = '10000';
                customMenuItem.style.top = `${event.clientY}px`;
                customMenuItem.style.left = `${event.clientX}px`;
                customMenuItem.style.boxShadow = '0 2px 10px rgba(0,0,0,0.5)';
                customMenuItem.style.borderRadius = '3px';

                const clickHandler = async function() {
                    try {
                        const response = await fetch(link.href, {
                            method: 'HEAD',
                            redirect: 'manual'
                        });

                        const realUrl = response.headers.get('location') || link.href;

                        GM_setClipboard(realUrl);
                        showTemporaryMessage(`Real download URL copied to clipboard: ${realUrl}`, true);
                    } catch (error) {
                        console.error('Error fetching the real download URL:', error);
                        showTemporaryMessage('Failed to get the real download URL.', false);
                    } finally {
                        document.body.removeChild(customMenuItem);
                    }
                };

                customMenuItem.addEventListener('click', clickHandler);

                document.body.appendChild(customMenuItem);

                const cleanup = () => {
                    if (customMenuItem.parentNode) {
                        customMenuItem.removeEventListener('click', clickHandler);
                        document.body.removeChild(customMenuItem);
                    }
                };

                // Cleanup after 5 seconds or when clicking elsewhere
                setTimeout(cleanup, 5000);
                document.addEventListener('click', cleanup, { once: true });

                // Prevent propagation to avoid closing the default context menu
                customMenuItem.addEventListener('contextmenu', function(e) {
                    e.stopPropagation();
                    e.preventDefault();
                });

                // Prevent default context menu from showing
                event.preventDefault();
            }
        }
    });

    function showTemporaryMessage(message, success) {
        const msgDiv = document.createElement('div');
        msgDiv.textContent = message;
        msgDiv.style.position = 'fixed';
        msgDiv.style.bottom = '10px';
        msgDiv.style.right = '10px';
        msgDiv.style.backgroundColor = success ? 'green' : 'red';
        msgDiv.style.color = 'white';
        msgDiv.style.padding = '10px';
        msgDiv.style.borderRadius = '5px';
        msgDiv.style.zIndex = '10000';
        document.body.appendChild(msgDiv);
        setTimeout(() => {
            document.body.removeChild(msgDiv);
        }, 1000);
    }
})();