反代

  • 网站代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    // Website you intended to retrieve for users.
    const upstream = 'feichang99.github.io'

    // Custom pathname for the upstream website.
    const upstream_path = '/'

    // Website you intended to retrieve for users using mobile devices.
    const upstream_mobile = 'feichang99.github.io'

    // Countries and regions where you wish to suspend your service.
    const blocked_region = ['KP', 'SY', 'PK', 'CU']

    // IP addresses which you wish to block from using your service.
    const blocked_ip_address = ['0.0.0.0', '127.0.0.1']

    // Whether to use HTTPS protocol for upstream address.
    const https = true

    // Whether to disable cache.
    const disable_cache = false

    // Replace texts.
    const replace_dict = {
    '$upstream': '$custom_domain',
    '//feichang99.github.io': ''
    }

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

    async function fetchAndApply(request) {
    const region = request.headers.get('cf-ipcountry').toUpperCase();
    const ip_address = request.headers.get('cf-connecting-ip');
    const user_agent = request.headers.get('user-agent');

    let response = null;
    let url = new URL(request.url);
    let url_hostname = url.hostname;

    if (https == true) {
    url.protocol = 'https:';
    } else {
    url.protocol = 'http:';
    }

    if (await device_status(user_agent)) {
    var upstream_domain = upstream;
    } else {
    var upstream_domain = upstream_mobile;
    }

    url.host = upstream_domain;
    if (url.pathname == '/') {
    url.pathname = upstream_path;
    } else {
    url.pathname = upstream_path + url.pathname;
    }

    if (blocked_region.includes(region)) {
    response = new Response('Access denied: WorkersProxy is not available in your region yet.', {
    status: 403
    });
    } else if (blocked_ip_address.includes(ip_address)) {
    response = new Response('Access denied: Your IP address is blocked by WorkersProxy.', {
    status: 403
    });
    } else {
    let method = request.method;
    let request_headers = request.headers;
    let new_request_headers = new Headers(request_headers);

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

    let original_response = await fetch(url.href, {
    method: method,
    headers: new_request_headers
    })

    connection_upgrade = new_request_headers.get("Upgrade");
    if (connection_upgrade && connection_upgrade.toLowerCase() == "websocket") {
    return original_response;
    }

    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;

    if (disable_cache) {
    new_response_headers.set('Cache-Control', 'no-store');
    }

    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');

    if (new_response_headers.get("x-pjax-url")) {
    new_response_headers.set("x-pjax-url", response_headers.get("x-pjax-url").replace("//" + upstream_domain, "//" + url_hostname));
    }

    const content_type = new_response_headers.get('content-type');
    if (content_type != null && content_type.includes('text/html') && 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]
    if (i == '$upstream') {
    i = upstream_domain
    } else if (i == '$custom_domain') {
    i = host_name
    }

    if (j == '$upstream') {
    j = upstream_domain
    } else if (j == '$custom_domain') {
    j = host_name
    }

    let re = new RegExp(i, 'g')
    text = text.replace(re, j);
    }
    return text;
    }


    async function device_status(user_agent_info) {
    var agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
    var flag = true;
    for (var v = 0; v < agents.length; v++) {
    if (user_agent_info.indexOf(agents[v]) > 0) {
    flag = false;
    break;
    }
    }
    return flag;
    }
  • 网页代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    addEventListener('fetch', event => {
    event.respondWith(handleRequest(event.request))
    })

    // HTML代码
    let html = `
    <!DOCTYPE html>
    <html>
    <head><title>Test</title></head>
    <body><div>Hello world!</div></body>
    </html>
    `;

    /**
    * Respond to the request
    * @param {Request} request
    */
    async function handleRequest(request) {
    return new Response(html, {
    headers: {
    'Content-Type': 'text/html; charset=UTF-8'
    },
    status: 200
    })
    }

    来源….