Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add GM.xmlhttpRequest as alias of GM_xmlhttpRequest #1785

Closed
piquark6046 opened this issue Jul 26, 2023 · 2 comments
Closed

Add GM.xmlhttpRequest as alias of GM_xmlhttpRequest #1785

piquark6046 opened this issue Jul 26, 2023 · 2 comments

Comments

@piquark6046
Copy link
Member

piquark6046 commented Jul 26, 2023

Summary

GM_xmlhttpRequest and GM.xmlhttpRequest API cannot be used in an userscript when @grant GM.xmlhttpRequest is set instead of @grant GM_xmlhttpRequest.

The userscript works on the following environments:

  • a Chromium browser (Brave 1.56.11) + AdGuard Browser Extension 4.1.57 + Violentmonkey 2.15.0
  • Firefox browser + AdGuard Browser Extension 4.1.57 + Violentmonkey 2.15.0

Test page

Reference

https://github.com/List-KR/linkproduct-privacy (Tested version: 1.0.1)

@sfionov
Copy link
Member

sfionov commented Aug 3, 2023

@piquark6046 Does it reproduce with GM.xmlHttpRequest with capital H?

GM.xmlhttpRequest does not exist in specification. Old version has small h, and GM4 version has capital H.

@piquark6046
Copy link
Member Author

Yes. The bug can be reproduced even if GM.xmlHttpRequest is used.

Screenshot

image

Code

// ==UserScript==
// @name         linkproduct-privacy
// @encoding     utf-8
// @namespace    https://github.com/List-KR/linkproduct-privacy
// @homepageURL  https://github.com/List-KR/linkproduct-privacy
// @supportURL   https://github.com/List-KR/linkproduct-privacy/issues
// @updateURL    https://cdn.jsdelivr.net/gh/List-KR/linkproduct-privacy@main/linkproduct-privacy.user.js
// @downloadURL  https://cdn.jsdelivr.net/gh/List-KR/linkproduct-privacy@main/linkproduct-privacy.user.js
// @license      MIT
//
// @version      1.2.4
// @author       PiQuark6046 and contributors
//
// @match        *://*/*
//
// @description        linkproduct-privacy can get original URL from an affiliate marketing URL.
// @description:ko     linkproduct-privacy는 인플루언서 마케팅 URL에서 원본 URL을 얻을 수 있습니다.
//
// @grant        unsafeWindow
// @grant        GM_xmlhttpRequest
// @run-at       document-end
// ==/UserScript==
(function () {
    const GMXmlhttpRequest = typeof GM.xmlHttpRequest !== 'undefined' ? GM.xmlHttpRequest : GM_xmlhttpRequest;
    const LinkProductURLs = [
        {
            URLPattern: '//app.ac/'
        },
        {
            URLPattern: '//link.coupang.com/a/'
        },
        {
            URLPattern: '//link.coupang.com/a/'
        },
        {
            URLPattern: '//link.coupang.com/re/'
        },
        {
            URLPattern: '//qoo.tn/'
        },
        {
            URLPattern: '//s.click.aliexpress.com/s/'
        },
        {
            URLPattern: 'bbs/link.php?bo_table=hot&',
            OnSite: 'etoland.co.kr'
        },
        {
            URLPattern: '//click.linkprice.com/click.php?'
        }
    ];
    const LinkResultURLs = [
        {
            URLPattern: /^https:\/\/[a-z]+\.gmarket\.co\.kr\/linkprice\/lpfront\.asp/,
            ModificationFunction: function (ResultURL) {
                let SearchParamsURL = new URL(ResultURL).searchParams.get('url');
                let OriginalURL = new URL(SearchParamsURL);
                OriginalURL.searchParams.delete('jaehuid');
                return OriginalURL.href;
            }
        },
        {
            URLPattern: /^https:\/\/[a-z]+\.wemakeprice\.com\/product\/[0-9]+/,
            ModificationFunction: function (ResultURL) {
                let Oringin = new URL(ResultURL).origin;
                let Pathname = new URL(ResultURL).pathname;
                return Oringin + Pathname;
            }
        },
        {
            URLPattern: /^https:\/\/[a-z]+\.coupang\.com\/vp\/products\/[0-9]+/,
            ModificationFunction: function (ResultURL) {
                let Oringin = new URL(ResultURL).origin;
                let Pathname = new URL(ResultURL).pathname;
                return Oringin + Pathname;
            }
        },
        {
            URLPattern: /^https?:\/\/m?item(page[0-9]+)?\.auction\.co\.kr\/[A-z]+(\.[a-z]+)?\?item(N|n)o=[A-z0-9]+/,
            ModificationFunction: function (ResultURL) {
                return /^https?:\/\/m?item(page[0-9]+)?\.auction\.co\.kr\/[A-z]+(\.[a-z]+)?\?item(N|n)o=[A-z0-9]+/.exec(ResultURL)[0];
            }
        },
        {
            URLPattern: /^https:\/\/(www|m)\.qoo10\.com\/g\/[0-9]+/,
            ModificationFunction: function (ResultURL) {
                return /^https:\/\/(www|m)\.qoo10\.com\/g\/[0-9]+/.exec(ResultURL)[0];
            }
        },
        {
            URLPattern: /^https:\/\/(www|m)\.e-himart\.co\.kr\/common\/include\/ipfront.jsp\?lpinfo=/,
            ModificationFunction: function (ResultURL) {
                return new URL(ResultURL).searchParams.get('url');
            }
        },
        {
            URLPattern: /^https?:\/\/(www|m)\.11st\.co\.kr\/connect\/Gateway\.tmall\?apInfo=.+&lpUrl=/,
            ModificationFunction: function (ResultURL) {
                let LpURL = new URL(ResultURL).searchParams.get('lpUrl');
                return new URL(LpURL).search === '' ? LpURL : new URL(LpURL).origin + new URL(LpURL).pathname;
            }
        },
        {
            URLPattern: /^https:\/\/[a-z]+\.coupang\.com\/np\/campaigns\/[0-9]+/,
            ModificationFunction: function (ResultURL) {
                let Oringin = new URL(ResultURL).origin;
                let Pathname = new URL(ResultURL).pathname;
                return Oringin + Pathname;
            }
        },
        {
            URLPattern: /^https:\/\/pages\.coupang\.com\/p\/[A-z0-9]+/,
            ModificationFunction: function (ResultURL) {
                let Oringin = new URL(ResultURL).origin;
                let Pathname = new URL(ResultURL).pathname;
                return Oringin + Pathname;
            }
        },
        {
            URLPattern: /^https:\/\/[a-z]+\.lotteon\.com\/m\/product\/[A-z0-9]+/,
            ModificationFunction: function (ResultURL) {
                let Oringin = new URL(ResultURL).origin;
                let Pathname = new URL(ResultURL).pathname;
                return Oringin + Pathname;
            }
        },
        {
            URLPattern: /^https:\/\/(m\.)?[a-z]+\.aliexpress\.com\/item\/[0-9]+\.html/,
            ModificationFunction: function (ResultURL) {
                let Oringin = new URL(ResultURL).origin;
                let Pathname = new URL(ResultURL).pathname;
                return Oringin + Pathname;
            }
        },
        {
            URLPattern: /^https:\/\/etoland\.co\.kr\/bbs\/link\.php\?bo_table=hot&/,
            ModificationFunction: function (ResultURL, ResultElement) {
                return ResultElement.innerText;
            }
        }
    ];
    let LinkElements = Array.from(document.querySelectorAll(LinkProductURLs.filter(function (LinkProductURL) {
        return typeof LinkProductURL.OnSite === 'undefined' || document.location.hostname.includes(LinkProductURL.OnSite);
    }).map(function (Value) { return `a[href*="${Value.URLPattern}"]`; }).join(', ')));
    console.debug('linkproduct-privacy: LinkElements: ', LinkElements);
    for (let LinkElement of LinkElements) {
        let URLAddress = LinkElement.getAttribute('href');
        if (URLAddress === null) {
            console.warn('linkproduct-privacy: URLAddress is null.', LinkElement);
            continue;
        }
        GMXmlhttpRequest({ url: URLAddress, method: 'GET', responseType: 'document', anonymous: true, onload: function (ResponseObject) {
                let UpdateURL;
                let ResponseURL = ResponseObject.responseURL || ResponseObject.finalUrl;
                for (let i = 0; i < LinkResultURLs.length; i++) {
                    if (LinkResultURLs[i].URLPattern.test(ResponseURL)) {
                        UpdateURL = LinkResultURLs[i].ModificationFunction(ResponseURL, LinkElement);
                        console.debug('linkproduct-privacy: The reponse URL matches a predefined URL:', {
                            'Element': LinkElement, 'Affiliate marketing URL': URLAddress, 'Response URL': ResponseURL, 'Processed URL': UpdateURL
                        });
                        break;
                    }
                    if (LinkResultURLs.length - 1 === i) {
                        UpdateURL = ResponseURL;
                        console.warn('linkproduct-privacy: The reponse URL does NOT match any predefined URL:', {
                            'Element': LinkElement, 'Affiliate marketing URL': URLAddress, 'Response URL': ResponseURL
                        });
                    }
                }
                LinkElement.setAttribute('href', UpdateURL);
                if (/^(http(s|):)?\/\/.+\..+\/.+/.test(LinkElement.innerText))
                    LinkElement.innerText = UpdateURL;
            } });
    }
})();

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

5 participants