解析下载Chrome浏览器的WebStore(谷歌商店)的扩展程序-LMLPHP

最近在获取edge商店应用下载地址时遇到点麻烦,没有解决。转头去研究chrome商店的扩展下载地址,看到了大佬分享的方法,这里顺便记录一下。

首先进入chrome应用商店找到自己想要下载的应用,比如:

https://chrome.google.com/webstore/detail/adblocker-stop-ad-on-ever/gpbfjnhlnemfnhajnmkjicfmbagfbejm?hl=zh-CN

从URL地址端可以看到,其扩展ID是 gpbfjnhlnemfnhajnmkjicfmbagfbejm

下面是拼接规则:

https://clients2.google.com/service/update2/crx?response=redirect&prodversion=[PRODVERSION]&acceptformat=crx2,crx3&x=id%3D[EXTENSIONID]%26uc

  • EXTENSIONID = 扩展ID(gpbfjnhlnemfnhajnmkjicfmbagfbejm
  • PRODVERSION = chrome版本。原文作者注明必须为31.0.1609.0以上,这里可以实际通用填写为:9999.0.9999.0
  • acceptformat = crx2,crx3 是2018年新增的,如没有则会响应 204 状态码,很多人的答案这里是没有的。

那么可以根据这个方法拼接得出如下地址:

https://clients2.google.com/service/update2/crx?response=redirect&prodversion=9999.0.9999.0&acceptformat=crx2,crx3&x=id%3Dgpbfjnhlnemfnhajnmkjicfmbagfbejm%26uc

这里有一个完整的拼接函数,可以参考一下:

function getPlatformInfo() {
    var platformInfo = localStorage.getItem('platformInfo');
    if (!platformInfo) {
        return getPlatformInfoFallback();
    }
    platformInfo = JSON.parse(platformInfo);
    // Firefox does not have nacl_arch.
    if (!platformInfo.nacl_arch) {
        platformInfo.nacl_arch = getPlatformInfoFallback().nacl_arch;
    }
    return platformInfo;
}


function getPlatformInfoFallback() {
    var os;
    var arch;

    // For the definition of the navigator object, see Chromium's source code:
    //  third_party/WebKit/Source/core/page/NavigatorBase.cpp
    //  webkit/common/user_agent/user_agent_util.cc

    // UA := "Mozilla/5.0 (%s) AppleWebKit/%d.%d (KHTML, like Gecko) %s Safari/%d.%d"
    //                     ^^                                        ^^
    //                     Platform + CPUinfo                        Product, Chrome/d.d.d.d
    var ua = navigator.userAgent;
    ua = ua.split('AppleWebKit')[0] || ua;
    // After splitting, we get the next string:
    // ua := "5.0 (%s) "

    // The string in comments is the line with the actual definition in user_agent_util.cc,
    // unless said otherwise.
    if (ua.indexOf('Mac') >= 0) {
        // "Intel Mac OS X %d_%d_%d",
        os = 'mac';
    } else if (ua.indexOf('Win') >= 0) {
        // "Windows NT %d.%d%s",
        os = 'win';
    } else if (ua.indexOf('Android') >= 0) {
        // Note: "Linux; " is preprended, so test Android before Linux
        // "Android %s%s",
        os = 'android';
    } else if (ua.indexOf('CrOS') >= 0) {
        // "CrOS "
        // "%s %d.%d.%d",
        os = 'cros';
    } else if (ua.indexOf('BSD') >= 0) {
        os = 'openbsd';
    } else { // if (ua.indexOf('Linux') >= 0) {
        os = 'linux';
    }

    if (/\barm/.test(ua)) {
        arch = 'arm';
    } else if (/[^.0-9]64(?![.0-9])/.test(ua)) {
        // WOW64, Win64, amd64, etc. Assume 64-bit arch when there's a 64 in the string, not surrounded
        // by dots or digits (this restriction is set to avoid matching version numbers)
        arch = 'x86-64';
    } else {
        arch = 'x86-32';
    }
    return {
        os: os,
        arch: arch,
        nacl_arch: arch
    };
}
function get_crx_url(extensionID_or_url) {
    var url;
    var match = ows_pattern.exec(extensionID_or_url);
    if (match) {
        url = 'https://addons.opera.com/extensions/download/';
        url += match[1];
        url += '/';
        return url;
    }
    match = amo_pattern.exec(extensionID_or_url);
    if (match) {
        return get_xpi_url(match[1], match[2]);
    }
    match = amo_file_version_pattern.exec(extensionID_or_url);
    if (match) {
        return 'https://' + match[1] + '/firefox/downloads/file/' + match[2] + (match[3] || '/addon.xpi');
    }
    // Chrome Web Store
    match = get_extensionID(extensionID_or_url);
    var extensionID = match ? match : extensionID_or_url;

    if (!/^[a-z]{32}$/.test(extensionID)) {
        return extensionID_or_url;
    }

    var platformInfo = getPlatformInfo();

    // Omitting this value is allowed, but add it just in case.
    // Source: https://cs.chromium.org/file:update_query_params.cc%20GetProdIdString
    var product_id = isChromeNotChromium() ? 'chromecrx' : 'chromiumcrx';
    // Channel is "unknown" on Chromium on ArchLinux, so using "unknown" will probably be fine for everyone.
    var product_channel = 'unknown';
    // As of July, the Chrome Web Store sends 204 responses to user agents when their
    // Chrome/Chromium version is older than version 31.0.1609.0
    var product_version = '9999.0.9999.0';
    // Try to detect the Chrome version, and if it is lower than 31.0.1609.0, use a very high version.
    // $1 = m.0.r.p  // major.minor.revision.patch where minor is always 0 for some reason.
    // $2 = m
    // $3 =     r
    var cr_version = /Chrome\/((\d+)\.0\.(\d+)\.\d+)/.exec(navigator.userAgent);
    if (cr_version && +cr_version[2] >= 31 && +cr_version[3] >= 1609) {
        product_version = cr_version[1];
    }

    url = 'https://clients2.google.com/service/update2/crx?response=redirect';
    url += '&os=' + platformInfo.os;
    url += '&arch=' + platformInfo.arch;
    url += '&os_arch=' + platformInfo.arch; // crbug.com/709147 - should be archName of chrome.system.cpu.getInfo
    url += '&nacl_arch=' + platformInfo.nacl_arch;
    url += '&prod=' + product_id;
    url += '&prodchannel=' + product_channel;
    url += '&prodversion=' + product_version;
    url += '&acceptformat=crx2,crx3';
    url += '&x=id%3D' + extensionID;
    url += '%26uc';
    return url;
}

最后是这个答案的原文地址:https://stackoverflow.com/a/14099762

03-11 18:49