Sending form data fails on Deno 1.13.2
Hi.
I get an error when I send form data using ky.post method on Deno 1.13.2.
Error message is below:
error: Uncaught (in promise) TypeError: Unreachable
at mainFetch (deno:ext/fetch/26_fetch.js:190:33)
It is no problem on Deno 1.11.5.
But on Deno 1.13.2, it fails.
Even though raw fetch (globalThis.fetch) succeeds.
ky.post with json also succeeds.
There may be some discrepancies between what your library expects and the latest Deno implementation.
I tried using a Deno Docker container. The command used is:
docker run -v /[path-to-dir-includes-my-sample-file]:/tmp/test -it --rm denoland/deno:debian-1.13.2 run --unstable -A /tmp/test/my-sample.ts
This is my sample code:
// my-sample.ts
import ky from 'https://cdn.skypack.dev/ky?dts';
// prepare parameters
const url = 'https://example.com';
const json = { hoge: 'hoge' };
const formData = new FormData();
formData.append('hoge', 'hoge');
// Deno's raw fetch post with FormData
console.log('\nTry fetch post.');
let r = await fetch(url, { method: 'POST' , body: formData });
console.log('Success? :', r.ok);
// ky post with JSON
console.log('\nTry ky post with JSON.');
r = await ky.post(url, { json: json });
console.log('Success? :', r.ok);
// ky post with FormData
console.log('\nTry ky post with FormData.');
r = await ky.post(url, { body: formData }); // will fail
console.log('Success? :', r.ok);
results:
Try fetch post.
Success? : true
Try ky post with JSON.
Success? : true
Try ky post with FormData.
error: Uncaught (in promise) TypeError: Unreachable
at mainFetch (deno:ext/fetch/26_fetch.js:190:33)
I am able to reproduce. I bisected the Deno version and found that Deno 1.12.0 is where it breaks.
The error message points to this line in Deno's code:
https://github.com/denoland/deno/blob/1563088f060b1f1d4826bb3a6d4120b276a4e15f/ext/fetch/26_fetch.js#L178
So I guess the request URL is being turned into a Blob URL somehow? Not sure why that would be happening. We're certainly not doing that intentionally and given that we're not having this problem in other environments or on older versions of Deno, I'm inclined to say this should be reported to the Deno team as a regression. But it's possible we're doing something funky - needs more investigation.
Repro code:
import ky from 'https://cdn.skypack.dev/ky?dts'
const url = 'https://httpbin.org/anything';
const body = new FormData();
body.append('username', 'janedoe');
// const response = await fetch(url, { method : 'POST', body });
const response = await ky.post(url, { body });
console.log('response:', response);
console.log('form:', (await response.json()).form);
I found that wrapping the form data in a URLSearchParams works.
const url = 'https://example.com';
const formData = new FormData();
formData.append('username', 'test');
r = await ky.post(url, { body: new URLSearchParams(formData) });
It's caused by https://github.com/denoland/deno/issues/16570 , fetch(request.clone()) does not work in Deno when there is a stream body.
https://github.com/sindresorhus/ky/blob/577dd4c5e36f214930a22247523a73d37847c335/source/core/Ky.ts#L298