MiniValine 使用 Cloudflare Workers 反代LeanCloud API

发表于: 7/27/2022

MiniValine

Cloudflare Workers

LeanCloud国际版

:::info 通过严谨的阅读公告,更深刻的理解了下内容,仅仅是不提供共享域名,你可以通过绑定自己的域名来继续使用服务。

不过本文的努力也没有全部白费,使用Workers可以隐藏自己的Key,防止被奇奇怪怪的使用,甚至可以自己加点佐料,就这么安慰下自己吧。 :::

首先,8 月 1 日起,国际版共享域名不再向中国大陆提供服务

官网公告

虽然链接404,但是公告可没有移除。

为了继续快乐白嫖,折腾了一整天,终于找到了解决方案!!并解决了解决方案里的问题成功上线!!

原本的代码写的一言难尽之余,跨域的访问一旦出错就是CORS error,也真是天才般的设计。别人的问题在于给不支持跨域的API包装跨域,也许本方案不需要处理跨域也说不定…

需要格外注意的是修改访问人数是PUT请求,复制request的时候要对body特殊处理。

同时由于Cloudflare Workers自带域名*.workers.dev也是在我朝不可用的状态,需要配置自定义域名。Cloudflare Workers的设置中已经提供了功能。 经尝试似乎要添加redirect: "follow"才能正常访问。

:::info 自定义域名需要域名托管于 Cloudflare DNS 下,并且确认你的SSL设置不为Off以提供HTTPS访问,避免mixed content。 :::

随后修改serverURLs为你的Workers,按你的心情决定是否隐藏AppKey。

!!各种错误轮番出现已经人晕了,每次改一点儿再撤销都回不到一个地方!!{.blur} !!既然现在能用了我也懒得再改什么了,有人能提供优化的话也欢迎留言!!{.blur} !!最开始还想在 MiniValine 基础上加个后端,结果 clone 下来一看!!{.blur} !!代码像个麻花扭在一起,注入调用乱飞,告辞,我跟动态语言水火不容!!{.blur}

// src/index.js
var AppId = "--------------";
var AppKey = "--------------";
var ORIGINS = {
  "---------------": "----------------"
};
var corsHeaders = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Methods": "GET,PUT,DELETE,HEAD,POST,OPTIONS",
  "Access-Control-Max-Age": "86400"
};
var src_default = {
  async fetch(request) {
    let rq = new Request(request, { redirect: "follow" });
    return handleRequest(rq);
  }
};
async function handleRequest(request) {
  if (request.method === "OPTIONS") {
    return handleOptions(request);
  }
  const url = new URL(request.url);
  if (request.headers.get('Origin') in ORIGINS) {
    // const target = ORIGINS[url.hostname];
    url.hostname = "---------------":;
    let reqHEDNew = new Headers(request.headers);
    if (reqHEDNew.get("X-LC-Id")) {
      reqHEDNew.set("X-LC-Id", AppId);
      reqHEDNew.set("X-LC-Key", AppKey);
    }
    if (reqHEDNew.get("x-lc-sign")) {
      reqHEDNew.delete("x-lc-sign");
    }
    let reqNew;
    if (request.method === "PUT")
      reqNew = { method: "PUT", headers: reqHEDNew, body: await request.arrayBuffer() };
    else
      reqNew = new Request(request, { headers: reqHEDNew });
    let responsefetch = await fetch(url.toString(), reqNew);
    let resHEDNew = new Headers(responsefetch.headers);
    let response = new Response(responsefetch.body, { headers: resHEDNew });
    response.headers.set("Access-Control-Allow-Origin", "*");
    response.headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    return response;
  }
  return new Response("nothing here");
}

async function handleOptions(request) {
  let headers = request.headers;
  if (headers.get("Origin") !== null && headers.get("Access-Control-Request-Method") !== null && headers.get("Access-Control-Request-Headers") !== null) {
    let respHeaders = {
      ...corsHeaders,
      "Access-Control-Allow-Headers": request.headers.get("Access-Control-Request-Headers")
    };
    return new Response(null, {
      headers: respHeaders
    });
  } else {
    return new Response(null, {
      headers: {
        Allow: "GET, HEAD, PUT,DELETE, POST, OPTIONS"
      }
    });
  }
}
export {
  src_default as default
};
//# sourceMappingURL=index.js.map