更多示例代码

简介: 这段代码展示了EdgeRoutine的多个功能示例,包括处理不同的请求类型(如hello world、地理位置信息获取、转发请求等)、实现AB测试、多源拼接、预加载、竞速请求、简单边缘侧日志记录、重定向(基于UserAgent和地理位置信息)及拒绝爬虫访问等。每个功能通过独立函数实现,并在主处理函数中根据请求类型调用相应的处理逻辑。具体效果可参考[Yopian的示例](https://www.yopian.com/sitemap/post.xml)。

EdgeRoutine的示例源码

addEventListener("fetch", function(event) {
event.respondWith(_handleRouter(event));
});
async function _handleRouter(event) {
let json = await event.request.json();
if (json) {
let name = json.name代码效果参考:https://www.yopian.com/sitemap/post.xml
switch(name) {
case "helloworld":
return _handleHelloWorld(event);
case "geo":
return _handleGeo(event);
case "fetch":
return _handleFetch(event, json);
case "request":
return _handleRequest(event, json);
case "response":
return _handleResponse(event, json);
// Cases
case "ab-test":
return _handleABTest(event, json);
case "multi-origin":
return _handleMultipleOriginConcate(event, json);
case "prefetch":
return _handlePrefetch(event, json);
case "race":
return _handleRace(event, json);
case "esi":
return _handleESI(event, json);
case "log":
return _handleEdgeLog(event, json);
case "3xx":
return _handleRedirect3XX(event, json);
case "redirect":
return _handleRedirectGeneral(event, json);
case "deny-bot":
return _handleDenyBot(event, json);
case "waf":
return _handleWAF(event, json);
default:
break;
}
}
return new Response(
{ error : "invalid request" },
{
"status" : 403 ,
"statusText" : "Forbidden"
});
}
async function _handleHelloWorld(event) {
return new Response("Hello World!");
}
async function _handleGeo(event) {
const info = event.info;
let remote_addr = info.remote_addr;
let ip_isp_en = info.ip_isp_en;
let ip_city_en = info.ip_city_en;
let ip_region_en = info.ip_region_en;
let ip_country_en = info.ip_country_en;
let scheme = info.scheme;
let detector_device = info.detector_device;
let content = Geo: ${remote_addr}, \ ${ip_isp_en}, \ ${ip_country_en}, \ ${ip_city_en}, \ ${ip_region_en},\ ${scheme}, \ ${detector_device};
return new Response(content);
}
async function _handleFetch(event, json) {
let fetchURL = json.url;
if (fetchURL) {
return await fetch(fetchURL);
}
return fetch("http://default.ialicdn.com");
}
async function _handleRequest(event, json) {
let headers = json.headers;
let body = json.body;
const fetchInit = {
body : body,
headers: headers
};
return fetch("http://default.ialicdn.com", fetchInit);
}
async function _handleResponse(event, json) {
let resp = await fetch("http://default.ialicdn.com");
let headers = json.headers;
for (var k in headers) {
resp.headers.set(k, headers[k]);
}
return resp;
}
/* ================

  • (1) DevOps |
  • =================/
    function _shouldDoABTest(request) {
    // (1) if request's user agent match a certain string
    {
    const ua = request.headers.get("user-agent");
    if (ua && ua.match(/canary-client/)) {
    return true;
    }
    }
    // (2) whether we have special header
    {
    return request.headers.has("x-ab-test");
    }
    }
    async function _handleABTest(event, json) {
    event.request.headers.delete("content-length");
    const fetchInit = {
    method : event.request.method,
    headers: event.request.headers,
    body : "empty"
    };
    if (_shouldDoABTest(event.request)) {
    return fetch("http://default.ialicdn.com/dev", fetchInit);
    } else {
    return fetch("http://default.ialicdn.com", fetchInit);
    }
    }
    /** ==================================
  • (2) Multiple Origin Concatenation |
    ==================================*/
    async function _handleMultipleOriginConcate(event, json) {
    const respInit = {
    headers: event.request.headers,
    body : json.body
    };
    // (1) We try to concate www.alipay.com and www.tmall.com together
    let {readable, writable} = new TransformStream();
    async function controller() {
    let r1 = await fetch("http://www.alipay.com");
    let r2 = await fetch("https://www.tmall.com");
    await r1.body.pipeTo(writable, {preventClose: true});
    await r2.body.pipeTo(writable);
    }
    controller();
    return new Response(readable, respInit);
    }
    /
    ==================================*
  • (3) Precache/Prefetch |
    ==================================*/
    async function _fetchAndIgnore(url) {
    try {
    // Specify cdnProxy flag to make sure the request goes through the CDN
    let resp = await fetch(url);//, {cdnProxy: true});
    // Make sure to ignore the content otherwise the cache may not be valid
    await resp.ignore();
    } catch (e) {
    console.error("invalid URL: %s", url);
    }
    }
    async function _doPrefetchURLAsync(prefetchURL, event) {
    for (const url of prefetchURL) {
    event.waitUntil(_fetchAndIgnore(url));
    }
    }
    async function _handlePrefetch(event, json) {
    {
    const prefetchURL = json.prefetch;
    if (prefetchURL) {
    // Do not await it and let it run in background
    _doPrefetchURLAsync(prefetchURL, event);
    return new Response("Done Prefetch");
    }
    }
    return new Response("Miss Prefetch");
    }
    /
    ==================================*
  • (4) Race
    ==================================*/
    async function _handleRace(event, json) {
    let fetchList = json.fetchList;
    if (fetchList) {
    return Promise.race(fetchList.map((x) => fetch(x)));
    } else {
    return "forget to include fetchList field in your JSON";
    }
    }
    /
    ==================================*
  • (5) Simple ESI
    * ==================================/
    async function _handleESI(request, json) {
    let { readable, writable } = new TransformStream();
    let newResponse = new Response(readable);
    if (!json.esi) {
    return "forget to include template field in your JSON";
    }
    streamTransformBody(new BufferStream(json.esi), writable);
    return newResponse;
    }
    async function handleTemplate(encoder, templateKey) {
    const linkRegex = new RegExp("esi:include.src=@(.)@.*", 'gm');
    let result = linkRegex.exec(templateKey);
    let esi = "unknown";
    if (!result) {
    return encoder.encode(<${templateKey}>);
    }
    if (result[1]) {
    esi = await subRequests(result[1]);
    }
    return encoder.encode(${esi});
    }
    async function subRequests(target){
    const init = {method: 'GET'};
    let response = await fetch(target, init);
    let text = await response.text();
    return text;
    }
    async function streamTransformBody(readable, writable) {
    const startTag = "<".charCodeAt(0);
    const endTag = ">".charCodeAt(0);
    let reader = readable.getReader();
    let writer = writable.getWriter();
    let templateChunks = null;
    while (true) {
    let { done, value } = await reader.read();
    if (done) break;
    while (value.byteLength > 0) {
    if (templateChunks) {
     let end = value.indexOf(endTag);
     if (end === -1) {
       templateChunks.push(value);
       break;
     } else {
       templateChunks.push(value.subarray(0, end));
       await writer.write(await translate(templateChunks));
       templateChunks = null;
       value = value.subarray(end + 1);
     }
    
    }
    let start = value.indexOf(startTag);
    if (start === -1) {
     await writer.write(value);
     break;
    
    } else {
     await writer.write(value.subarray(0, start));
     value = value.subarray(start + 1);
     templateChunks = [];
    
    }
    }
    }
    await writer.close();
    }
    async function translate(chunks) {
    const decoder = new TextDecoder();
    let templateKey = chunks.reduce(
    (accumulator, chunk) =>
    accumulator + decoder.decode(chunk, { stream: true }), "");
    templateKey += decoder.decode();
    return handleTemplate(new TextEncoder(), templateKey);
    }
    /* ==================================
  • (6) Edge side conditional log
    * ==================================/
    async function _doEdgeLog(data, writer) {
    let resp = await fetch("http://default.ialicdn.com/log",
    {
    method : "POST",
    body : data,
    headers: [["content-type", "application/json"]]
    });
    console.log("logged");
    {
    let stream = new BufferStream("++++++++++++++++++++++++++++++\n");
    await stream.pipeTo(writer, {preventClose: true});
    }
    await resp.body.pipeTo(writer);
    }
    async function _handleEdgeLog(event, json) {
    let start= Date.now();
    let resp = await fetch("http://default.ialicdn.com", {
    method : event.request.method,
    headers: event.request.headers,
    body : json.body
    });
    // Get a promise that is fired when we send out everything
    let {readable, writable} = new TransformStream();
    // (1) first let the fetch request's response goes back and then we post
    // the log back as well internally
    let endPromise = resp.body.pipeTo(writable, {preventClose: true});
    // (2) wait for endPromise to be fired to make sure that the body has been
    // piped back to the client, and then we do the log
    event.waitUntil(endPromise.then(
    (v) => {
    let end = Date.now();
    let diff= (end - start);
    try {
     // You have to await your async promise since wait until is not
     // usable currently maybe. User can use wait until only before
     // returning the main request for now
     event.waitUntil(_doEdgeLog(`{ "cost(millisecond)" : ${diff} }`, writable));
    
    } catch (e) {
     console.error(`${e}`);
    
    }
    },
    (v) => {
    writable.abort();
    console.error("failed");
    }));
    console.error("XXXX");
    // return the response back
    return new Response(readable, {
    status: resp.status,
    headers: resp.headers
    });
    }
    /* ==================================
  • (7) redirect-3xx
    ==================================*/
    async function _handleRedirect3XX(event, json) {
    return fetch("http://www.taobao.com", {redirect: "follow"});
    }
    /
    ==================================*
  • (8) redirect
  • (1) UserAgent
  • (2) Geo information
    ==================================*/
    async function _handleRedirectGeneral(event, json) {
    const fetchInit = {
    method : event.request.method,
    body : json.body,
    headers : event.request.headers
    };
    {
    const ua = event.request.headers.get("user-agent");
    if (ua && ua.match(/firefox/i)) {
    return fetch("http://default.ialicdn.com/firefox", fetchInit);
    }
    if (ua && ua.match(/safari/i)) {
    return fetch("http://default.ialicdn.com/safari", fetchInit);
    }
    }
    {
    if (event.info.detect_device && event.info.detect_device.match(/iphone/)) {
    return fetch("http://default.ialicdn.com/iphone", fetchInit);
    }
    }
    return new Response("unknown request", {status: 403});
    }
    /
    ==================================*
  • (9) Deny bot
    ==================================*/
    async function _handleDenyBot(event, json) {
    {
    const ua = event.request.headers.get("user-agent");
    if (ua && ua.match(new RegExp("xxxspider", "i"))) {
    return new Response("Forbidden", {status: 403});
    }
    }
    return fetch("http://default.ialicdn.com");
    }
    /
    ==================================*
  • (10) Simple WAF
    * ==================================/
    async function _handleWAF(event, json) {
    let city = json.city;
    if (event.info.ip_city_en === city) {
    return new Response("Forbidden", {status: 403});
    }
    // back to origin
    return (JSON.stringify(event.info));
    }
相关文章
如何在文档中添加示例代码
【10月更文挑战第17天】在文档中添加示例代码是非常重要的,它可以帮助读者更好地理解和使用所介绍的内容。
|
7月前
|
异构计算
LabVIEW关于USRPRIO的示例代码
LabVIEW关于USRPRIO的示例代码
50 2
|
5月前
|
API PHP 开发者
​邮件发送API示例代码,AOKSend关于PHP示例代码
**邮件发送API简化了开发中的邮件功能,如自动化通知和营销邮件。常见示例包括SendGrid和Mailgun的Python代码。AOKSend在PHP中的使用示例展示了如何使用Guzzle库发送邮件,其特点包括高可靠性、易于集成和强大功能。通过API,开发者能高效、可靠地发送大规模邮件。**
|
5月前
|
监控 搜索推荐 Java
​邮件群发API,AOKSend关于Java示例代码
AOKSend邮件群发API简化了企业邮件自动化,提高效率,支持个性化内容和实时分析。其优势在于易于集成、高可靠性、丰富功能和详细统计。Java开发者可快速添加依赖,配置API密钥,使用示例代码发送邮件。通过AOKSend,企业能优化邮件策略,提升邮件营销效果。
|
算法 Java
Java 方法示例代码demo(一)
Java 方法示例代码demo(一)
65 0
|
Java
Java 方法示例代码demo(三)
Java 方法示例代码demo(三)
82 0
|
Java
Java 方法示例代码demo(二)
Java 方法示例代码demo(二)
57 0
|
Java
多线程实例代码(demo)
多线程实例代码(demo)
95 0
|
开发工具 对象存储 Python
需求文档及代码实现
compare hdfs & oss files
122 0
|
Python
如何使用Python代码实现赏月美景效果?
中秋节到来的时候,大多数人都喜欢看晚上的月亮,因为非常的好看。有句古话说得好“十五的月亮十六圆”,今年中秋节的景色真的非常美,真的让人难以忘记。于是,我也利用这个节日自己动手编写了代码,简单实现了一副中秋美景图。
514 3
如何使用Python代码实现赏月美景效果?
下一篇
DataWorks