使用cloudflare工作人员将文件上传到我的源服务器失败

问题描述 投票:0回答:1

我在 blog.domain.com 上托管了一个博客;我想使用 Cloudflare 工作人员将其从子域切换到子目录。除了文件上传之外一切正常。当我上传文件时,浏览器会发送带有 formData 的 xhr post 请求。

Request URL:
https://www.domain.in/blog/ghost/api/admin/images/upload/
Request Method:
POST
Status Code:
422 Unprocessable Content
Referrer Policy:
strict-origin-when-cross-origin

内容类型由浏览器设置用于文件上传

Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryglip7bP33nuVUYAE

Cloudflare 工作人员代码:

/**
 * Welcome to Cloudflare Workers! This is your first worker.
 *
 * - Run `npm run dev` in your terminal to start a development server
 * - Open a browser tab at http://localhost:8787/ to see your worker in action
 * - Run `npm run deploy` to publish your worker
 *
 * Learn more at https://developers.cloudflare.com/workers/
 */

export interface Env {
    // Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime-apis/kv/
    // MY_KV_NAMESPACE: KVNamespace;
    //
    // Example binding to Durable Object. Learn more at https://developers.cloudflare.com/workers/runtime-apis/durable-objects/
    // MY_DURABLE_OBJECT: DurableObjectNamespace;
    //
    // Example binding to R2. Learn more at https://developers.cloudflare.com/workers/runtime-apis/r2/
    // MY_BUCKET: R2Bucket;
    //
    // Example binding to a Service. Learn more at https://developers.cloudflare.com/workers/runtime-apis/service-bindings/
    // MY_SERVICE: Fetcher;
    //
    // Example binding to a Queue. Learn more at https://developers.cloudflare.com/queues/javascript-apis/
    // MY_QUEUE: Queue;
}

export default {
    async fetch(request : Request){
        async function handleRequest(request : Request) {
            const url = new URL(request.url);
            const originUrl = url.toString().replace("https://www.domain.in", "https://blog.domain.in");
            const cookieHeader = request.headers.get("Cookie");
            const headers = new Headers(request.headers);
        
            if (cookieHeader) {
              headers.append("Cookie", cookieHeader);
            }
        
            let originPage;
        
            if (["POST", "PUT", "DELETE"].includes(request.method)) {
              let contentType = request.headers.get("Content-Type") ;
              if (contentType && contentType.includes("multipart/form-data")) {
                let formData = await request.formData();
                originPage = await fetch(originUrl, {
                  method: request.method,
                  headers,
                  body: formData,
                });
              } else {
                originPage = await fetch(originUrl, {
                  method: request.method,
                  headers,
                  body: await request.text(),
                });
              }
            } else {
              originPage = await fetch(originUrl, {
                method: request.method,
                headers,
              });
            }
        
            const newResponse = new Response(originPage.body, originPage);
            return newResponse;
          };

        const response = await handleRequest(request);
        return response ;
    }
};


请求正在到达源服务器,但 multer 没有填充路径。所以文件上传被拒绝,说验证错误。 注意:当我从 blog.domain.in 上传时,上传工作正常(即没有 cloudflare 工作人员)

[90mValidationError: Please select an image.
    at uploadValidation (/var/lib/ghost/versions/5.74.0/core/server/web/api/middleware/upload.js:149:25)
    at Layer.handle [as handle_request] (/var/lib/ghost/versions/5.74.0/node_modules/express/lib/router/layer.js:95:5)
    at next (/var/lib/ghost/versions/5.74.0/node_modules/express/lib/router/route.js:144:13)
    at /var/lib/ghost/versions/5.74.0/core/server/web/api/middleware/upload.js:76:9
    at Immediate._onImmediate (/var/lib/ghost/versions/5.74.0/node_modules/multer/lib/make-middleware.js:53:37)
    at process.processImmediate (node:internal/timers:478:21)[39m
[39m
[2023-11-28 04:36:17] [31mERROR[39m The "path" argument must be of type string or an instance of Buffer or URL. Received undefined
[31m
[31mThe "path" argument must be of type string or an instance of Buffer or URL. Received undefined[39m

[1m[37mError Code: [39m[22m
    [90mERR_INVALID_ARG_TYPE[39m

可能是什么问题?预先感谢

wrangler.toml :

name = "ghost"
main = "src/index.ts"
compatibility_date = "2023-11-21"

route = { pattern = "https://www.domain.in/blog*", zone_name = "domain.in" }

fetch multer cloudflare ghost-blog cloudflare-workers
1个回答
0
投票

(发布我上面评论中的解决方案。)

麻烦从这里来:

let formData = await request.formData();
originPage = await fetch(originUrl, {
  method: request.method,
  headers,
  body: formData,
});

此代码解析并重新编码表单数据。这意味着将选择一个新的边界字符串。但是,原始请求中的 Content-Type 标头将被转移到子请求,并且它包含旧的边界字符串,该字符串对于新编码无效。您可以通过删除 Content-Type 标头来解决此问题,在这种情况下,Workers Runtime 将根据新的 FormData 编码自动重新生成它:

let formData = await request.formData();
headers.delete("Content-Type");
originPage = await fetch(originUrl, {
  method: request.method,
  headers,
  body: formData,
});
© www.soinside.com 2019 - 2024. All rights reserved.