基于 CloudFlare Workers 搭建 WordPress 反代节点

材料准备:

  • 1个二级域名
  • 1个 CloudFlare 账号
  • 一定的JS基础(只需要会复制粘贴)

步骤一:添加域名到 CloudFlare

此步不再介绍,建议添加 proxy 子域, ip 随便填写即可。

步骤二:明确需要反代的链接和其对应反代的链接

我们一共需要反代10个网址( Gravatar 可有可无)

Workers名原站地址反代地址
wordpress-wpwordpress.orgproxy.你的域名/wordpress/wordpress/*
s-wps.w.orgproxy.你的域名/wordpress/s/*
ts-wpts.w.orgproxy.你的域名/wordpress/ts/*
downloads-wpdownloads.wordpress.orgproxy.你的域名/wordpress/downloads/*
ps-wpps.w.orgproxy.你的域名/wordpress/ps/*
developer-wpdeveloper.wordpress.orgproxy.你的域名/wordpress/developer/*
profiles-wpprofiles.wordpress.orgproxy.你的域名/wordpress/profiles/*
themes-wpwp-themes.comproxy.你的域名/wordpress/themes/*
api-wpapi.wordpress.orgproxy.你的域名/wordpress/api/*
gravatarsecure.gravatar.comproxy.你的域名/gravatar/*

步骤三:创建 Workers 并编写反代 JS

Github 上有现成的:https://github.com/Siujoeng-Lau/Workers-Proxy

不过直接拿来使用会出问题,我对其进行了修改(支持 POST 请求和缓存,优化替换。顺便精简了一堆无用代码)。

wordpress-wp:

//你的域名.
const proxy_domain = 'proxy.haozi.co';
//节点缓存时间.
const cache_times = 86400;

//下面的别瞎改了.
const upstream_domain = 'wordpress.org';
const replace_dict = {
    '//api.wordpress.org': '//' + proxy_domain + '/wordpress/api',
    '//ps.w.org': '//' + proxy_domain + '/wordpress/ps',
    '//downloads.wordpress.org': '//' + proxy_domain + '/wordpress/downloads',
    '//developer.wordpress.org': '//' + proxy_domain + '/wordpress/developer',
    '//profiles.wordpress.org': '//' + proxy_domain + '/wordpress/profiles',
    '//secure.gravatar.com/avatar': '//' + proxy_domain + '/gravatar',
    '//ts.w.org': '//' + proxy_domain + '/wordpress/ts',
    '//wp-themes.com': '//' + proxy_domain + '/wordpress/themes',
    '//s.w.org': '//' + proxy_domain + '/wordpress/s',
    '//wordpress.org': '//' + proxy_domain + '/wordpress/wordpress',
    '//gravatar.com': '//' + proxy_domain + '/gravatar'
};

addEventListener('fetch', event => {
    event.respondWith(fetchAndApply(event.request));
})

async function fetchAndApply(request) {

    let response = null;
    let url = new URL(request.url);
    let url_hostname = url.hostname;
    url.protocol = 'https:';
    url.host = upstream_domain;
    url.pathname = url.pathname.replace('/wordpress/wordpress', '');

    if (url.pathname != '/') {
        url.pathname = '/' + url.pathname;
    }

    let method = request.method;
    let request_headers = request.headers;
    let new_request_headers = new Headers(request_headers);
    var config;
    config = {
        method: method,
        headers: new_request_headers,
        cf: {
            'polish': 'lossless',
            'cacheTtl': cache_times,
        },
    };

    if (method == 'POST') {
        let reqBody = await request.text();
        config.body = reqBody;
    }

    new_request_headers.set('Host', upstream_domain);
    new_request_headers.set('Referer', url.protocol + '//' + url_hostname);

    let original_response = await fetch(url.href, config);
    let original_response_clone = original_response.clone();
    let original_text = null;
    let response_headers = original_response.headers;
    let new_response_headers = new Headers(response_headers);
    let status = original_response.status;

    new_response_headers.set('access-control-allow-origin', '*');
    new_response_headers.set('access-control-allow-credentials', true);
    new_response_headers.delete('content-security-policy');
    new_response_headers.delete('content-security-policy-report-only');
    new_response_headers.delete('clear-site-data');

    const content_type = new_response_headers.get('content-type');

    if (content_type != null && content_type.includes('text') || content_type.includes('utf-8')) {
        original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname);
    } else {
        original_text = original_response_clone.body;
    }

    response = new Response(original_text, {
        status,
        headers: new_response_headers
    });

    return response;
}

async function replace_response_text(response, upstream_domain, host_name) {

    let text = await response.text();
    var i, j;

    for (i in replace_dict) {
        j = replace_dict[i];
        let re = new RegExp(i, 'g');
        text = text.replace(re, j);
    }

    return text;
}

s-wp:

//你的域名.
const proxy_domain = 'proxy.haozi.co';
//节点缓存时间.
const cache_times = 864000;

//下面的别瞎改了.
const upstream_domain = 's.w.org';
const replace_dict = {
    '//api.wordpress.org': '//' + proxy_domain + '/wordpress/api',
    '//ps.w.org': '//' + proxy_domain + '/wordpress/ps',
    '//downloads.wordpress.org': '//' + proxy_domain + '/wordpress/downloads',
    '//developer.wordpress.org': '//' + proxy_domain + '/wordpress/developer',
    '//profiles.wordpress.org': '//' + proxy_domain + '/wordpress/profiles',
    '//secure.gravatar.com/avatar': '//' + proxy_domain + '/gravatar',
    '//ts.w.org': '//' + proxy_domain + '/wordpress/ts',
    '//wp-themes.com': '//' + proxy_domain + '/wordpress/themes',
    '//s.w.org': '//' + proxy_domain + '/wordpress/s',
    '//wordpress.org': '//' + proxy_domain + '/wordpress/wordpress',
    '//gravatar.com': '//' + proxy_domain + '/gravatar'
};

addEventListener('fetch', event => {
    event.respondWith(fetchAndApply(event.request));
})

async function fetchAndApply(request) {

    let response = null;
    let url = new URL(request.url);
    let url_hostname = url.hostname;
    url.protocol = 'https:';
    url.host = upstream_domain;
    url.pathname = url.pathname.replace('/wordpress/s', '');

    if (url.pathname != '/') {
        url.pathname = '/' + url.pathname;
    }

    let method = request.method;
    let request_headers = request.headers;
    let new_request_headers = new Headers(request_headers);
    var config;
    config = {
        method: method,
        headers: new_request_headers,
        cf: {
            'polish': 'lossless',
            'cacheTtl': cache_times,
        },
    };

    if (method == 'POST') {
        let reqBody = await request.text();
        config.body = reqBody;
    }

    new_request_headers.set('Host', upstream_domain);
    new_request_headers.set('Referer', url.protocol + '//' + url_hostname);

    let original_response = await fetch(url.href, config);
    let original_response_clone = original_response.clone();
    let original_text = null;
    let response_headers = original_response.headers;
    let new_response_headers = new Headers(response_headers);
    let status = original_response.status;

    new_response_headers.set('access-control-allow-origin', '*');
    new_response_headers.set('access-control-allow-credentials', true);
    new_response_headers.delete('content-security-policy');
    new_response_headers.delete('content-security-policy-report-only');
    new_response_headers.delete('clear-site-data');

    const content_type = new_response_headers.get('content-type');

    if (content_type != null && content_type.includes('text') || content_type.includes('utf-8')) {
        original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname);
    } else {
        original_text = original_response_clone.body;
    }

    response = new Response(original_text, {
        status,
        headers: new_response_headers
    });

    return response;
}

async function replace_response_text(response, upstream_domain, host_name) {

    let text = await response.text();
    var i, j;

    for (i in replace_dict) {
        j = replace_dict[i];
        let re = new RegExp(i, 'g');
        text = text.replace(re, j);
    }

    return text;
}

ts-wp:

//你的域名.
const proxy_domain = 'proxy.haozi.co';
//节点缓存时间.
const cache_times = 864000;

//下面的别瞎改了.
const upstream_domain = 'ts.w.org';
const replace_dict = {
    '//api.wordpress.org': '//' + proxy_domain + '/wordpress/api',
    '//ps.w.org': '//' + proxy_domain + '/wordpress/ps',
    '//downloads.wordpress.org': '//' + proxy_domain + '/wordpress/downloads',
    '//developer.wordpress.org': '//' + proxy_domain + '/wordpress/developer',
    '//profiles.wordpress.org': '//' + proxy_domain + '/wordpress/profiles',
    '//secure.gravatar.com/avatar': '//' + proxy_domain + '/gravatar',
    '//ts.w.org': '//' + proxy_domain + '/wordpress/ts',
    '//wp-themes.com': '//' + proxy_domain + '/wordpress/themes',
    '//s.w.org': '//' + proxy_domain + '/wordpress/s',
    '//wordpress.org': '//' + proxy_domain + '/wordpress/wordpress',
    '//gravatar.com': '//' + proxy_domain + '/gravatar'
};

addEventListener('fetch', event => {
    event.respondWith(fetchAndApply(event.request));
})

async function fetchAndApply(request) {

    let response = null;
    let url = new URL(request.url);
    let url_hostname = url.hostname;
    url.protocol = 'https:';
    url.host = upstream_domain;
    url.pathname = url.pathname.replace('/wordpress/ts', '');

    if (url.pathname != '/') {
        url.pathname = '/' + url.pathname;
    }

    let method = request.method;
    let request_headers = request.headers;
    let new_request_headers = new Headers(request_headers);
    var config;
    config = {
        method: method,
        headers: new_request_headers,
        cf: {
            'polish': 'lossless',
            'cacheTtl': cache_times,
        },
    };

    if (method == 'POST') {
        let reqBody = await request.text();
        config.body = reqBody;
    }

    new_request_headers.set('Host', upstream_domain);
    new_request_headers.set('Referer', url.protocol + '//' + url_hostname);

    let original_response = await fetch(url.href, config);
    let original_response_clone = original_response.clone();
    let original_text = null;
    let response_headers = original_response.headers;
    let new_response_headers = new Headers(response_headers);
    let status = original_response.status;

    new_response_headers.set('access-control-allow-origin', '*');
    new_response_headers.set('access-control-allow-credentials', true);
    new_response_headers.delete('content-security-policy');
    new_response_headers.delete('content-security-policy-report-only');
    new_response_headers.delete('clear-site-data');

    const content_type = new_response_headers.get('content-type');

    if (content_type != null && content_type.includes('text') || content_type.includes('utf-8')) {
        original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname);
    } else {
        original_text = original_response_clone.body;
    }

    response = new Response(original_text, {
        status,
        headers: new_response_headers
    });

    return response;
}

async function replace_response_text(response, upstream_domain, host_name) {

    let text = await response.text();
    var i, j;

    for (i in replace_dict) {
        j = replace_dict[i];
        let re = new RegExp(i, 'g');
        text = text.replace(re, j);
    }

    return text;
}

downloads-wp:

//你的域名.
const proxy_domain = 'proxy.haozi.co';
//节点缓存时间.
const cache_times = 864000;

//下面的别瞎改了.
const upstream_domain = 'downloads.wordpress.org';
const replace_dict = {
    '//api.wordpress.org': '//' + proxy_domain + '/wordpress/api',
    '//ps.w.org': '//' + proxy_domain + '/wordpress/ps',
    '//downloads.wordpress.org': '//' + proxy_domain + '/wordpress/downloads',
    '//developer.wordpress.org': '//' + proxy_domain + '/wordpress/developer',
    '//profiles.wordpress.org': '//' + proxy_domain + '/wordpress/profiles',
    '//secure.gravatar.com/avatar': '//' + proxy_domain + '/gravatar',
    '//ts.w.org': '//' + proxy_domain + '/wordpress/ts',
    '//wp-themes.com': '//' + proxy_domain + '/wordpress/themes',
    '//s.w.org': '//' + proxy_domain + '/wordpress/s',
    '//wordpress.org': '//' + proxy_domain + '/wordpress/wordpress',
    '//gravatar.com': '//' + proxy_domain + '/gravatar'
};

addEventListener('fetch', event => {
    event.respondWith(fetchAndApply(event.request));
})

async function fetchAndApply(request) {

    let response = null;
    let url = new URL(request.url);
    let url_hostname = url.hostname;
    url.protocol = 'https:';
    url.host = upstream_domain;
    url.pathname = url.pathname.replace('/wordpress/downloads', '');

    if (url.pathname != '/') {
        url.pathname = '/' + url.pathname;
    }

    let method = request.method;
    let request_headers = request.headers;
    let new_request_headers = new Headers(request_headers);
    var config;
    config = {
        method: method,
        headers: new_request_headers,
        cf: {
            'polish': 'lossless',
            'cacheTtl': cache_times,
        },
    };

    if (method == 'POST') {
        let reqBody = await request.text();
        config.body = reqBody;
    }

    new_request_headers.set('Host', upstream_domain);
    new_request_headers.set('Referer', url.protocol + '//' + url_hostname);

    let original_response = await fetch(url.href, config);
    let original_response_clone = original_response.clone();
    let original_text = null;
    let response_headers = original_response.headers;
    let new_response_headers = new Headers(response_headers);
    let status = original_response.status;

    new_response_headers.set('access-control-allow-origin', '*');
    new_response_headers.set('access-control-allow-credentials', true);
    new_response_headers.delete('content-security-policy');
    new_response_headers.delete('content-security-policy-report-only');
    new_response_headers.delete('clear-site-data');

    const content_type = new_response_headers.get('content-type');

    if (content_type != null && content_type.includes('text') || content_type.includes('utf-8')) {
        original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname);
    } else {
        original_text = original_response_clone.body;
    }

    response = new Response(original_text, {
        status,
        headers: new_response_headers
    });

    return response;
}

async function replace_response_text(response, upstream_domain, host_name) {

    let text = await response.text();
    var i, j;

    for (i in replace_dict) {
        j = replace_dict[i];
        let re = new RegExp(i, 'g');
        text = text.replace(re, j);
    }

    return text;
}

ps-wp:

//你的域名.
const proxy_domain = 'proxy.haozi.co';
//节点缓存时间.
const cache_times = 864000;

//下面的别瞎改了.
const upstream_domain = 'ps.w.org';
const replace_dict = {
    '//api.wordpress.org': '//' + proxy_domain + '/wordpress/api',
    '//ps.w.org': '//' + proxy_domain + '/wordpress/ps',
    '//downloads.wordpress.org': '//' + proxy_domain + '/wordpress/downloads',
    '//developer.wordpress.org': '//' + proxy_domain + '/wordpress/developer',
    '//profiles.wordpress.org': '//' + proxy_domain + '/wordpress/profiles',
    '//secure.gravatar.com/avatar': '//' + proxy_domain + '/gravatar',
    '//ts.w.org': '//' + proxy_domain + '/wordpress/ts',
    '//wp-themes.com': '//' + proxy_domain + '/wordpress/themes',
    '//s.w.org': '//' + proxy_domain + '/wordpress/s',
    '//wordpress.org': '//' + proxy_domain + '/wordpress/wordpress',
    '//gravatar.com': '//' + proxy_domain + '/gravatar'
};

addEventListener('fetch', event => {
    event.respondWith(fetchAndApply(event.request));
})

async function fetchAndApply(request) {

    let response = null;
    let url = new URL(request.url);
    let url_hostname = url.hostname;
    url.protocol = 'https:';
    url.host = upstream_domain;
    url.pathname = url.pathname.replace('/wordpress/ps', '');

    if (url.pathname != '/') {
        url.pathname = '/' + url.pathname;
    }

    let method = request.method;
    let request_headers = request.headers;
    let new_request_headers = new Headers(request_headers);
    var config;
    config = {
        method: method,
        headers: new_request_headers,
        cf: {
            'polish': 'lossless',
            'cacheTtl': cache_times,
        },
    };

    if (method == 'POST') {
        let reqBody = await request.text();
        config.body = reqBody;
    }

    new_request_headers.set('Host', upstream_domain);
    new_request_headers.set('Referer', url.protocol + '//' + url_hostname);

    let original_response = await fetch(url.href, config);
    let original_response_clone = original_response.clone();
    let original_text = null;
    let response_headers = original_response.headers;
    let new_response_headers = new Headers(response_headers);
    let status = original_response.status;

    new_response_headers.set('access-control-allow-origin', '*');
    new_response_headers.set('access-control-allow-credentials', true);
    new_response_headers.delete('content-security-policy');
    new_response_headers.delete('content-security-policy-report-only');
    new_response_headers.delete('clear-site-data');

    const content_type = new_response_headers.get('content-type');

    if (content_type != null && content_type.includes('text') || content_type.includes('utf-8')) {
        original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname);
    } else {
        original_text = original_response_clone.body;
    }

    response = new Response(original_text, {
        status,
        headers: new_response_headers
    });

    return response;
}

async function replace_response_text(response, upstream_domain, host_name) {

    let text = await response.text();
    var i, j;

    for (i in replace_dict) {
        j = replace_dict[i];
        let re = new RegExp(i, 'g');
        text = text.replace(re, j);
    }

    return text;
}

developer-wp:

//你的域名.
const proxy_domain = 'proxy.haozi.co';
//节点缓存时间.
const cache_times = 86400;

//下面的别瞎改了.
const upstream_domain = 'developer.wordpress.org';
const replace_dict = {
    '//api.wordpress.org': '//' + proxy_domain + '/wordpress/api',
    '//ps.w.org': '//' + proxy_domain + '/wordpress/ps',
    '//downloads.wordpress.org': '//' + proxy_domain + '/wordpress/downloads',
    '//developer.wordpress.org': '//' + proxy_domain + '/wordpress/developer',
    '//profiles.wordpress.org': '//' + proxy_domain + '/wordpress/profiles',
    '//secure.gravatar.com/avatar': '//' + proxy_domain + '/gravatar',
    '//ts.w.org': '//' + proxy_domain + '/wordpress/ts',
    '//wp-themes.com': '//' + proxy_domain + '/wordpress/themes',
    '//s.w.org': '//' + proxy_domain + '/wordpress/s',
    '//wordpress.org': '//' + proxy_domain + '/wordpress/wordpress',
    '//gravatar.com': '//' + proxy_domain + '/gravatar'
};

addEventListener('fetch', event => {
    event.respondWith(fetchAndApply(event.request));
})

async function fetchAndApply(request) {

    let response = null;
    let url = new URL(request.url);
    let url_hostname = url.hostname;
    url.protocol = 'https:';
    url.host = upstream_domain;
    url.pathname = url.pathname.replace('/wordpress/developer', '');

    if (url.pathname != '/') {
        url.pathname = '/' + url.pathname;
    }

    let method = request.method;
    let request_headers = request.headers;
    let new_request_headers = new Headers(request_headers);
    var config;
    config = {
        method: method,
        headers: new_request_headers,
        cf: {
            'polish': 'lossless',
            'cacheTtl': cache_times,
        },
    };

    if (method == 'POST') {
        let reqBody = await request.text();
        config.body = reqBody;
    }

    new_request_headers.set('Host', upstream_domain);
    new_request_headers.set('Referer', url.protocol + '//' + url_hostname);

    let original_response = await fetch(url.href, config);
    let original_response_clone = original_response.clone();
    let original_text = null;
    let response_headers = original_response.headers;
    let new_response_headers = new Headers(response_headers);
    let status = original_response.status;

    new_response_headers.set('access-control-allow-origin', '*');
    new_response_headers.set('access-control-allow-credentials', true);
    new_response_headers.delete('content-security-policy');
    new_response_headers.delete('content-security-policy-report-only');
    new_response_headers.delete('clear-site-data');

    const content_type = new_response_headers.get('content-type');

    if (content_type != null && content_type.includes('text') || content_type.includes('utf-8')) {
        original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname);
    } else {
        original_text = original_response_clone.body;
    }

    response = new Response(original_text, {
        status,
        headers: new_response_headers
    });

    return response;
}

async function replace_response_text(response, upstream_domain, host_name) {

    let text = await response.text();
    var i, j;

    for (i in replace_dict) {
        j = replace_dict[i];
        let re = new RegExp(i, 'g');
        text = text.replace(re, j);
    }

    return text;
}

profiles-wp:

//你的域名.
const proxy_domain = 'proxy.haozi.co';
//节点缓存时间.
const cache_times = 86400;

//下面的别瞎改了.
const upstream_domain = 'profiles.wordpress.org';
const replace_dict = {
    '//api.wordpress.org': '//' + proxy_domain + '/wordpress/api',
    '//ps.w.org': '//' + proxy_domain + '/wordpress/ps',
    '//downloads.wordpress.org': '//' + proxy_domain + '/wordpress/downloads',
    '//developer.wordpress.org': '//' + proxy_domain + '/wordpress/developer',
    '//profiles.wordpress.org': '//' + proxy_domain + '/wordpress/profiles',
    '//secure.gravatar.com/avatar': '//' + proxy_domain + '/gravatar',
    '//ts.w.org': '//' + proxy_domain + '/wordpress/ts',
    '//wp-themes.com': '//' + proxy_domain + '/wordpress/themes',
    '//s.w.org': '//' + proxy_domain + '/wordpress/s',
    '//wordpress.org': '//' + proxy_domain + '/wordpress/wordpress',
    '//gravatar.com': '//' + proxy_domain + '/gravatar'
};

addEventListener('fetch', event => {
    event.respondWith(fetchAndApply(event.request));
})

async function fetchAndApply(request) {

    let response = null;
    let url = new URL(request.url);
    let url_hostname = url.hostname;
    url.protocol = 'https:';
    url.host = upstream_domain;
    url.pathname = url.pathname.replace('/wordpress/profiles', '');

    if (url.pathname != '/') {
        url.pathname = '/' + url.pathname;
    }

    let method = request.method;
    let request_headers = request.headers;
    let new_request_headers = new Headers(request_headers);
    var config;
    config = {
        method: method,
        headers: new_request_headers,
        cf: {
            'polish': 'lossless',
            'cacheTtl': cache_times,
        },
    };

    if (method == 'POST') {
        let reqBody = await request.text();
        config.body = reqBody;
    }

    new_request_headers.set('Host', upstream_domain);
    new_request_headers.set('Referer', url.protocol + '//' + url_hostname);

    let original_response = await fetch(url.href, config);
    let original_response_clone = original_response.clone();
    let original_text = null;
    let response_headers = original_response.headers;
    let new_response_headers = new Headers(response_headers);
    let status = original_response.status;

    new_response_headers.set('access-control-allow-origin', '*');
    new_response_headers.set('access-control-allow-credentials', true);
    new_response_headers.delete('content-security-policy');
    new_response_headers.delete('content-security-policy-report-only');
    new_response_headers.delete('clear-site-data');

    const content_type = new_response_headers.get('content-type');

    if (content_type != null && content_type.includes('text') || content_type.includes('utf-8')) {
        original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname);
    } else {
        original_text = original_response_clone.body;
    }

    response = new Response(original_text, {
        status,
        headers: new_response_headers
    });

    return response;
}

async function replace_response_text(response, upstream_domain, host_name) {

    let text = await response.text();
    var i, j;

    for (i in replace_dict) {
        j = replace_dict[i];
        let re = new RegExp(i, 'g');
        text = text.replace(re, j);
    }

    return text;
}

themes-wp:

//你的域名.
const proxy_domain = 'proxy.haozi.co';
//节点缓存时间.
const cache_times = 864000;

//下面的别瞎改了.
const upstream_domain = 'wp-themes.com';
const replace_dict = {
    '//api.wordpress.org': '//' + proxy_domain + '/wordpress/api',
    '//ps.w.org': '//' + proxy_domain + '/wordpress/ps',
    '//downloads.wordpress.org': '//' + proxy_domain + '/wordpress/downloads',
    '//developer.wordpress.org': '//' + proxy_domain + '/wordpress/developer',
    '//profiles.wordpress.org': '//' + proxy_domain + '/wordpress/profiles',
    '//secure.gravatar.com/avatar': '//' + proxy_domain + '/gravatar',
    '//ts.w.org': '//' + proxy_domain + '/wordpress/ts',
    '//wp-themes.com': '//' + proxy_domain + '/wordpress/themes',
    '//s.w.org': '//' + proxy_domain + '/wordpress/s',
    '//wordpress.org': '//' + proxy_domain + '/wordpress/wordpress',
    '//gravatar.com': '//' + proxy_domain + '/gravatar'
};

addEventListener('fetch', event => {
    event.respondWith(fetchAndApply(event.request));
})

async function fetchAndApply(request) {

    let response = null;
    let url = new URL(request.url);
    let url_hostname = url.hostname;
    url.protocol = 'https:';
    url.host = upstream_domain;
    url.pathname = url.pathname.replace('/wordpress/themes', '');

    if (url.pathname != '/') {
        url.pathname = '/' + url.pathname;
    }

    let method = request.method;
    let request_headers = request.headers;
    let new_request_headers = new Headers(request_headers);
    var config;
    config = {
        method: method,
        headers: new_request_headers,
        cf: {
            'polish': 'lossless',
            'cacheTtl': cache_times,
        },
    };

    if (method == 'POST') {
        let reqBody = await request.text();
        config.body = reqBody;
    }

    new_request_headers.set('Host', upstream_domain);
    new_request_headers.set('Referer', url.protocol + '//' + url_hostname);

    let original_response = await fetch(url.href, config);
    let original_response_clone = original_response.clone();
    let original_text = null;
    let response_headers = original_response.headers;
    let new_response_headers = new Headers(response_headers);
    let status = original_response.status;

    new_response_headers.set('access-control-allow-origin', '*');
    new_response_headers.set('access-control-allow-credentials', true);
    new_response_headers.delete('content-security-policy');
    new_response_headers.delete('content-security-policy-report-only');
    new_response_headers.delete('clear-site-data');

    const content_type = new_response_headers.get('content-type');

    if (content_type != null && content_type.includes('text') || content_type.includes('utf-8')) {
        original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname);
    } else {
        original_text = original_response_clone.body;
    }

    response = new Response(original_text, {
        status,
        headers: new_response_headers
    });

    return response;
}

async function replace_response_text(response, upstream_domain, host_name) {

    let text = await response.text();
    var i, j;

    for (i in replace_dict) {
        j = replace_dict[i];
        let re = new RegExp(i, 'g');
        text = text.replace(re, j);
    }

    return text;
}

api-wp:

//你的域名.
const proxy_domain = 'proxy.haozi.co';
//节点缓存时间.
const cache_times = -1;

//下面的别瞎改了.
const upstream_domain = 'api.wordpress.org';
const replace_dict = {
    '/\api.wordpress.org': '/' + proxy_domain + '/wordpress/api',
    '/\ps.w.org': '/' + proxy_domain + '/wordpress/ps',
    '/\downloads.wordpress.org': '/' + proxy_domain + '/wordpress/downloads',
    '/\developer.wordpress.org': '/' + proxy_domain + '/wordpress/developer',
    '/\profiles.wordpress.org': '/' + proxy_domain + '/wordpress/profiles',
    '/\secure.gravatar.com/avatar': '/' + proxy_domain + '/gravatar',
    '/\ts.w.org': '/' + proxy_domain + '/wordpress/ts',
    '/\wp-themes.com': '/' + proxy_domain + '/wordpress/themes',
    '/\s.w.org': '/' + proxy_domain + '/wordpress/s',
    '/\wordpress.org': '/' + proxy_domain + '/wordpress/wordpress',
    '/\gravatar.com': '/' + proxy_domain + '/gravatar',
    '/\0.gravatar.com': '/' + proxy_domain + '/gravatar',
    '/\1.gravatar.com': '/' + proxy_domain + '/gravatar',
    '/\2.gravatar.com': '/' + proxy_domain + '/gravatar',
};

addEventListener('fetch', event => {
    event.respondWith(fetchAndApply(event.request));
})

async function fetchAndApply(request) {

    let response = null;
    let url = new URL(request.url);
    let url_hostname = url.hostname;
    url.protocol = 'https:';
    url.host = upstream_domain;
    url.pathname = url.pathname.replace('/wordpress/api', '');

    if (url.pathname != '/') {
        url.pathname = '/' + url.pathname;
    }

    let method = request.method;
    let request_headers = request.headers;
    let new_request_headers = new Headers(request_headers);
    var config;
    config = {
        method: method,
        headers: new_request_headers,
        cf: {
            'polish': 'lossless',
            'cacheTtl': cache_times,
        },
    };

    if (method == 'POST') {
        let reqBody = await request.text();
        config.body = reqBody;
    }

    new_request_headers.set('Host', upstream_domain);
    new_request_headers.set('Referer', url.protocol + '//' + url_hostname);

    let original_response = await fetch(url.href, config);
    let original_response_clone = original_response.clone();
    let original_text = null;
    let response_headers = original_response.headers;
    let new_response_headers = new Headers(response_headers);
    let status = original_response.status;

    new_response_headers.set('access-control-allow-origin', '*');
    new_response_headers.set('access-control-allow-credentials', true);
    new_response_headers.delete('content-security-policy');
    new_response_headers.delete('content-security-policy-report-only');
    new_response_headers.delete('clear-site-data');

    const content_type = new_response_headers.get('content-type');

    if (content_type != null && content_type.includes('text') || content_type.includes('utf-8') || content_type.includes('json')) {
        original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname);
    } else {
        original_text = original_response_clone.body;
    }

    response = new Response(original_text, {
        status,
        headers: new_response_headers
    });

    return response;
}

async function replace_response_text(response, upstream_domain, host_name) {

    let text = await response.text();
    var i, j;

    for (i in replace_dict) {
        j = replace_dict[i];
        let re = new RegExp(i, 'g');
        text = text.replace(re, j);
    }

    return text;
}

gravatar:

//你的域名.
const proxy_domain = 'proxy.haozi.co';
//节点缓存时间.
const cache_times = 86400;

//下面的别瞎改了.
const upstream_domain = 'secure.gravatar.com';
const replace_dict = {
    's.gravatar.com': proxy_domain + '/gravatar',
    '0.gravatar.com': proxy_domain + '/gravatar',
    '1.gravatar.com': proxy_domain + '/gravatar',
    '2.gravatar.com': proxy_domain + '/gravatar',
    'www.gravatar.com': proxy_domain + '/gravatar'
};

addEventListener('fetch', event => {
    event.respondWith(fetchAndApply(event.request));
})

async function fetchAndApply(request) {

    let response = null;
    let url = new URL(request.url);
    let url_hostname = url.hostname;
    url.protocol = 'https:';
    url.host = upstream_domain;
    url.pathname = url.pathname.replace('/gravatar', '');

    if (url.pathname != '/') {
        url.pathname = '/' + url.pathname;
    }

    let method = request.method;
    let request_headers = request.headers;
    let new_request_headers = new Headers(request_headers);
    var config;
    config = {
        method: method,
        headers: new_request_headers,
        cf: {
            'polish': 'lossless',
            'cacheTtl': cache_times,
        },
    };

    if (method == 'POST') {
        let reqBody = await request.text();
        config.body = reqBody;
    }

    new_request_headers.set('Host', upstream_domain);
    new_request_headers.set('Referer', url.protocol + '//' + url_hostname);

    let original_response = await fetch(url.href, config);
    let original_response_clone = original_response.clone();
    let original_text = null;
    let response_headers = original_response.headers;
    let new_response_headers = new Headers(response_headers);
    let status = original_response.status;

    new_response_headers.set('access-control-allow-origin', '*');
    new_response_headers.set('access-control-allow-credentials', true);
    new_response_headers.delete('content-security-policy');
    new_response_headers.delete('content-security-policy-report-only');
    new_response_headers.delete('clear-site-data');

    const content_type = new_response_headers.get('content-type');

    if (content_type != null && content_type.includes('text') || content_type.includes('utf-8')) {
        original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname);
    } else {
        original_text = original_response_clone.body;
    }

    response = new Response(original_text, {
        status,
        headers: new_response_headers
    });

    return response;
}

async function replace_response_text(response, upstream_domain, host_name) {

    let text = await response.text();
    var i, j;

    for (i in replace_dict) {
        j = replace_dict[i];
        let re = new RegExp(i, 'g');
        text = text.replace(re, j);
    }

    return text;
}

接下来将代码中默认的域名proxy.haozi.co替换为自己的反代域名。

缓存时间根据自己需要设置,单位为秒。-1为不缓存

步骤四:设置执行 Workers 的路由

参考下表:

路由Worker
proxy.你的域名/gravatar*gravatar
proxy.你的域名/wordpress/api*api-wp
proxy.你的域名/developer*developer-wp
proxy.你的域名/downloads*downloads-wp
proxy.你的域名/profiles*profiles-wp
proxy.你的域名/ps*ps-wp
proxy.你的域名/s*s-wp
proxy.你的域名/themes*themes-wp
proxy.你的域名/ts*ts-wp
proxy.你的域名/wordpress/wordpress*wordpress-wp

全部设置完以后应该是这样的:

随便测试访问检查是否正常。

例子:proxy.你的域名/wordpress/wordpress

无误后将信息填入 WP-China-Yes 插件即可

proxy.你的域名/wordpress/api
proxy.你的域名/wordpress/downloads

已知问题:

  • 小概率内部错误(可能是用的免费版or自选节点的原因,持续观察中)已较长时间未出现。
  • 对不打tag更新的插件进行缓存会导致无法更新(downloads缓存时间设置-1可以解决)。
赞(1) 打赏
转载请保留出处:耗子博客 » 基于 CloudFlare Workers 搭建 WordPress 反代节点
分享到: 更多 (0)

评论 5

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #0

    路由设置的表格和图片不一样啊…Debug了半天才发现…

    Jack3个月前 (07-21)回复
    • 可以告诉下在哪个位置?当初写得比较快,有点错误难免。

      耗子3个月前 (07-22)回复
      • 就是 “全部设置完以后应该是这样的”这句话的上下,上面表格里的路由和下面设置完成后的路由不一样,上面表格里缺了”wordpress”,导致我直接copy表格去替换域名之后路由对不上,JS脚本和下面设置完的图里面是有”wordpress”的

        Jack3个月前 (07-22)回复
        • 我这边看是有这一项的,奇怪了

          耗子3个月前 (07-22)回复
  2. #0

    优秀!

    sUN6个月前 (05-08)回复

金额随意,一百两百也不介意的啦

支付宝扫一扫打赏

微信扫一扫打赏

Loading