Skip to content
New issue

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

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

Already on GitHub? Sign in 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;
            } });
    }
})();

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

No branches or pull requests

5 participants