将正文从请求转发到另一个 url

Forward body from request to another url

我想知道是否有人可以帮助弄清楚如何使用 cloudflare worker 将 post 正文传递到另一个端点? 我正在尝试获取传入请求 post 到 post 到 url。

const url = 'https://webhook.site/#!/b2f75ce2-7b9e-479a-b6f0-8934a89a3f3d'
const body = {
  results: ['default data to send'],
  errors: null,
  msg: 'I sent this to the fetch',
}

/**
 * gatherResponse awaits and returns a response body as a string.
 * Use await gatherResponse(..) in an async function to get the response body
 * @param {Response} response
 */
async function gatherResponse(response) {
  const { headers } = response
  const contentType = headers.get('content-type') || ''
  if (contentType.includes('application/json')) {
    return JSON.stringify(await response.json())
  } else if (contentType.includes('application/text')) {
    return response.text()
  } else if (contentType.includes('text/html')) {
    return response.text()
  } else {
    return response.text()
  }
}

async function handleRequest() {
  const init = {
    body: JSON.stringify(body),
    method: 'POST',
    headers: {
      'content-type': 'application/json;charset=UTF-8',
    },
  }
  const response = await fetch(url, init)
  const results = await gatherResponse(response)
  return new Response(results, init)
}
addEventListener('fetch', (event) => {
  return event.respondWith(handleRequest())
})

我在 https://tight-art-0743.ctohm.workers.dev/, which basically forwards your POST request's body to a public requestbin. You can check what is it receiving at: https://requestbin.com/r/en5k768mcp4x9/24tqhPJw86mt2WjKRMbmt75FMH9

创建了一个工人
addEventListener("fetch", (event) => {
  event.respondWith(
    handleRequest(event.request).catch(
      (err) => new Response(err.stack, { status: 500 })
    )
  );
}); 

async function handleRequest(request) {
  let {method,headers}=request,
      url=new URL(request.url)
  // methods other than POST will return early
  if(method!=='POST') return new Response(`Your request method was ${method}`);

  const forwardRequest=new Request("https://en5k768mcp4x9.x.pipedream.net/", request)
  forwardRequest.headers.set('X-Custom-Header','hey!')
  return fetch(forwardRequest)
}

您可以看到它使用简单的 CURL 请求

curl --location --request POST 'https://tight-art-0743.ctohm.workers.dev/' \
--header 'Content-Type: application/json' \
--data-raw '{"environment": {"name": "Sample Environment Name (required)"}}'

工人代码中有两点值得注意:

  1. 我将原始请求作为 init 参数传递,通过它原始的 headers 和 body 被透明地转发到 requestbin,也允许一些额外的 header 需要时进行操作。
  2. 在这个例子中,我实际上并没有对请求做任何事情 body。因此没有必要等待它。您只需连接传入和传出流,让它们相互处理。

另一个例子:让我们添加一条/csv路由。以 /csv 开头的请求不会转发您的 POST body。相反,他们将下载一个远程 CSV 附件并将其 POST 到 requestbin。同样,我们并不是在等待实际的 CSV 内容。我们将响应的句柄body传递给转发请求

async function handleRequest(request) {
  let {method,headers}=request,
    url=new URL(request.url)
  if(method!=='POST')     return new Response(`Your request method was ${method}`);

  const forwardRequest=new Request("https://en5k768mcp4x9.x.pipedream.net/",request)
  if(url.pathname.includes('/csv')) {
    const remoteSource=`https://cdn.wsform.com/wp-content/uploads/2018/09/country_full.csv`,
          remoteResponse=await fetch(remoteSource)
    return fetch(forwardRequest,{body:remoteResponse.body})
  }  
  forwardRequest.headers.set('X-Custom-Header','hey!')
  return fetch(forwardRequest)
}

虽然您的代码理论上应该可以工作,但您正在展开响应这一事实意味着您的工作人员可能会由于达到时间限制、CPU 或内存而中止。相反,当使用基于流的方法时, 您的工作人员的执行在 returns 转发获取后立即完成。即使传出的 POST 仍然是 运行,也不受 CPU 或时间限制。