gsempe
gsempe

Reputation: 5499

Fetch PUT request gets Cache-Control header modified on Firefox and not Chrome

For the context, I'm creating presigned URL to upload to S3. For these requests the Cache-Control header has to be set to the value public, max-age=31536000, immutable.

I do the fetch with this code

fetch(
        uploadUrl,
        {
            method: 'PUT',
            cache: 'no-store',
            headers: { 'Content-Type': contentType, 'Cache-Control': 'public, max-age=31536000, immutable' },
            body: data
        })
        .then(response => {
            if (response.ok) {
                doneFunc(publicUrl);
            } else {
                failureFunc(response.status);
            }
        })
        .catch(response => {
            failureFunc(response.status);
        });

With Chrome the PUT request is actually sent with the Cache-Control header set in the fetch call public, max-age=31536000, immutable

With Firefox the PUT request is sent with the Cache-Control header set to public, max-age=31536000, immutable, no-cache. Notice the addition of no-cache at the end. This addition makes my presigned URL not valid.

I tried by removing the cache parameter, by setting it to no-cache and to no-store. Firefox always adds something to the Cache-Control header.

Do you know a way to make Firefox behaves like Chrome and respect the headers I set?

Upvotes: 1

Views: 1609

Answers (2)

Carlana
Carlana

Reputation: 1129

Colin Nicholson had the right answer for me, but it was buried in a comment, so I'm reposting it at the top level:

When the network tab is open in Safari or Firefox, they add an extra no-cache header which causes the presigned S3 URL PUT request to fail. Close the dev console and the upload should work.

Upvotes: 3

Aamir Shah
Aamir Shah

Reputation: 646

Try using the Headers object to add headers.

const headers = new Headers();
headers.append('Content-Type', contentType);
headers.append('cache-control', 'public, max-age=31536000, immutable, no-store');

fetch(
        uploadUrl,
        {
            method: 'PUT',
            headers: headers,
            body: data
        })
        .then(response => {
            if (response.ok) {
                doneFunc(publicUrl);
            } else {
                failureFunc(response.status);
            }
        })
        .catch(response => {
            failureFunc(response.status);
        });

My sample fetch request (if you want to test in firefox console)

const headers = new Headers();
headers.append('Content-Type', 'text/json');
headers.append('cache-control', 'public, max-age=31536000, immutable, no-custom');

const options = {
    method: 'PUT',
    headers: headers,
    body: JSON.stringify({})
};
fetch('https://www.mozilla.org/', options)
.then(response => console.log(response.ok ? 'done' : 'fail'))
.catch(response => console.log('fail catch'));

Upvotes: 1

Related Questions