Skip to content

Formdata send by Sveltekit Endpoint is send by plain/text with no data #5710

@garytube

Description

@garytube

Describe the bug

SvelteKit:

If you try to send a POST Request from Server-to-Server with FormData the request will fail.
Sveltekits fetch() does not set content-type multipart/form-data. The Request will be text/plain and no Formdata will be submitted

This probably relates to
#5349
#5292

I tried my best and created an Express Server and a Sveltekit App (see below) for debugging.

export const POST: RequestHandler = async ({ request }) => {
//	const formDataSendbyFrontend = await request.formData();
	const demoData = new FormData();
	demoData.append('data', "lorem ipsum");
	const res = await fetch('https://sveltekit-express-bug-tester.herokuapp.com/formdata', {
		method: 'POST',
		body: demoData
	})

The Request will fail, because Sveltekit sends text/plain and no FormData (???)

// Req Object Express Server
{
  body: {
    headers: {
      host: 'sveltekit-express-bug-tester.herokuapp.com',
      connection: 'close',
      accept: '*/*',
      'content-type': 'text/plain;charset=UTF-8',
      'accept-language': '*',
      'sec-fetch-mode': 'cors',
      'user-agent': 'undici',
      'accept-encoding': 'br, gzip, deflate',
      'x-request-id': '4f31b926-31c7-4cd2-a612-0bf85edb01fe',
      'x-forwarded-for': '1.1.1.1',
      'x-forwarded-proto': 'https',
      'x-forwarded-port': '443',
      via: '1.1 vegur',
      'connect-time': '0',
      'x-request-start': '1658828491278',
      'total-route-time': '0',
      'content-length': '17'
    },
    error: 'Not multipart/form-data'
  }
}

This used to Work with node-fetch and Sveltekit v.350 (not sure which version it got broken)

Reproduction

I prepared to Repos with a Server (Express + Multer) and a minimal Sveltekit App

💻 Server Repo: https://github.com/garytube/sveltekit-formdata-bug-server
🌍 Sveltekit Repo: https://github.com/garytube/sveltekit-formdata-bug-sveltekit

Send a POST Request with FormData from a SvelteKit Endpoint to http://sveltekit-express-bug-tester.herokuapp.com/formdata

	const demoData = new FormData();
	demoData.append('data', "lorem ipsum");
	const res = await fetch('http://sveltekit-express-bug-tester.herokuapp.com/formdata', {
		method: 'POST',
		body: demoData
	})

/formdata can also recive a File (Fieldname: image) (can be anything txt, jpg, pdf up to 1mb)
Maybe this helps debugging

<input bind:files  type="file" accept="image/*" />

formData.append('image', files[0]')

The Sveltekit Demo Project will

  1. Send Form Data to Sveltekit Endpoint
  2. Sveltekit Endpoint will forward Request TO OFF-SITE Server
  3. Request will fail because req.content-type of Sveltekit to OFF-SITE server is text/plain and formdata is missing

Logs

REQUEST LOG EXPRESS SERVER

2022-07-26T10:52:17.994877+00:00 app[web.1]: 415 {
2022-07-26T10:52:17.994884+00:00 app[web.1]:   headers: {
2022-07-26T10:52:17.994885+00:00 app[web.1]:     host: 'sveltekit-express-bug-tester.herokuapp.com',
2022-07-26T10:52:17.994886+00:00 app[web.1]:     connection: 'close',
2022-07-26T10:52:17.994887+00:00 app[web.1]:     'content-type': 'text/plain;charset=UTF-8',
2022-07-26T10:52:17.994887+00:00 app[web.1]:     accept: '*/*',
2022-07-26T10:52:17.994888+00:00 app[web.1]:     'accept-language': '*',
2022-07-26T10:52:17.994888+00:00 app[web.1]:     'sec-fetch-mode': 'cors',
2022-07-26T10:52:17.994888+00:00 app[web.1]:     'user-agent': 'undici',
2022-07-26T10:52:17.994889+00:00 app[web.1]:     'accept-encoding': 'br, gzip, deflate',
2022-07-26T10:52:17.994889+00:00 app[web.1]:     'x-request-id': '47463367-0ee3-4c57-b58a-cbdbf0d7cf68',
2022-07-26T10:52:17.994889+00:00 app[web.1]:     'x-forwarded-for': '-------------',
2022-07-26T10:52:17.994890+00:00 app[web.1]:     'x-forwarded-proto': 'https',
2022-07-26T10:52:17.994890+00:00 app[web.1]:     'x-forwarded-port': '443',
2022-07-26T10:52:17.994890+00:00 app[web.1]:     via: '1.1 vegur',
2022-07-26T10:52:17.994890+00:00 app[web.1]:     'connect-time': '0',
2022-07-26T10:52:17.994891+00:00 app[web.1]:     'x-request-start': '1658832737992',
2022-07-26T10:52:17.994891+00:00 app[web.1]:     'total-route-time': '0',
2022-07-26T10:52:17.994891+00:00 app[web.1]:     'content-length': '17'
2022-07-26T10:52:17.994892+00:00 app[web.1]:   },
2022-07-26T10:52:17.994892+00:00 app[web.1]:   file: undefined,
2022-07-26T10:52:17.994892+00:00 app[web.1]:   body: undefined
2022-07-26T10:52:17.994892+00:00 app[web.1]: }

System Info

System:
    OS: Windows 11
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 1.79 GB / 15.70 GB
  Binaries:
    Node: 18.1.0 - C:\Program Files\nodejs\node.EXE
    npm: 8.15.0 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: 103.0.5060.134
    Edge: Spartan (44.22000.120.0), Chromium (103.0.1264.71)
    Internet Explorer: 11.0.22000.120
  npmPackages:
    @sveltejs/adapter-auto: next => 1.0.0-next.63
    @sveltejs/kit: next => 1.0.0-next.394
    svelte: ^3.46.0 => 3.49.0
    vite: ^3.0.0 => 3.0.3

Severity

blocking an upgrade

Additional Information

Background:
My Realworld App is public Facing but only the Sveltekit Server is allowed to talk to the "Secure" API.
So instead of directly calling the "Secure" API from the Form, I send everything through the Sveltekit Server. This is why I need to send FromData Server-to-Server.

Used to work until undici came along ;)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions