Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New request in afterResponse hook with formData content #594

Open
jeanmatthieud opened this issue Jun 20, 2024 · 1 comment
Open

New request in afterResponse hook with formData content #594

jeanmatthieud opened this issue Jun 20, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@jeanmatthieud
Copy link

jeanmatthieud commented Jun 20, 2024

Hi,

I tried to upload some content with the FormData Web API and Ky (latest release).

Something like this:

const formData = new FormData();
formData.append('title', title);
formData.append('validityDate', validityDate);
formData.append('uploadFile[file]', new Blob([fileContent]));

return await api.post(`participant/${participantToken}/document`, { body: formData }).json<Document[]>();

I also have a custom ky instance, named in my example "api". This instance is based on the afterResponseHook example, to manage API authentication.

afterResponse: [
  async (request, options, response) => {
    if (response.status === 401) {
      // Get a fresh token
      const token = await ky('https://example.com/token').text();

      // Retry with the token
      request.headers.set('Authorization', `token ${token}`);

      return ky(request, options);
    }
  }
]

I discovered that the call to ky(request, options) doesn't regenerate the "content-type" header, which creates a boundary mismatch between the header and the request content.

I looked in the ky source code, and it seems that a patch already exists, but only for requests with searchParams, which is not my case:

if (

// To provide correct form boundary, Content-Type header should be deleted each time when new Request instantiated from another one
if (
	((supportsFormData && this._options.body instanceof globalThis.FormData)
		|| this._options.body instanceof URLSearchParams) && !(this._options.headers && (this._options.headers as Record<string, string>)['content-type'])
) {
	this.request.headers.delete('content-type');
}

if (this._options.searchParams) {

@sholladay
Copy link
Collaborator

A quick, non-ideal workaround on your end might be to change ky(request, options) to just ky(request). Does that solve it?

As for a more permanent fix, perhaps we should move the code for deleting content-type out of the searchParams condition. Hopefully that doesn't break anything...

@sholladay sholladay added the bug Something isn't working label Aug 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants