I am trying to name a pdf file that I am getting from a shared file on the network. I read that you can set the file name by setting a 'Content-Disposition" header which I am doing. But this is not saving the file name when I am viewing it in my client side. Here is the server side where I am grabbing a file from a shared computer and sending it to the client. Right now it has some weird file name inside the iframe. I have added the header to name the file how I think it should me named. I am able to console.log the filename but when I download or look at the filename in the properties it does not show what I console.log. Here is the server side:
import SMB2 from 'v9u-smb2';export async function GET({ url }: { url: { searchParams: URLSearchParams } }) { const plateID = url.searchParams.get('plateID') || ''; const smbOptions = { share: '\\\\fileName', domain: 'Domain Name', username: 'Username', password: 'Password', }; const smbClient = new SMB2(smbOptions); try { const filePath = 'PDF\\Piece_TEST_900442A.pdf'; // Use a Promise to handle the asynchronous file reading operation const fileContent = await new Promise<Uint8Array>((resolve, reject) => { smbClient.readFile(filePath, function (err, data) { if (err) { reject(err); } else { resolve(data as Uint8Array); } }); }); // Set the headers for the response const headers = new Headers(); headers.set('Content-Disposition', `inline; filename=${plateID}.pdf`); headers.set('Content-Type', 'application/pdf'); // Set the appropriate content type // Return the file content as a response return new Response(fileContent, { headers }); } catch (error) { console.error('Error: ', error); return new Response(JSON.stringify({ message: error }), { status: 500 }); } }
And here is my client side:
<script> import { onMount } from 'svelte'; import { goto } from '$app/navigation'; /** * @type {string} */ let pdfUrl; /** * @type {any} */ let plateID; async function showPDF() { try { const response = await fetch(`api/download?plateID=${plateID}`); if (response.ok) { const filename = getFilenameFromContentDisposition(response.headers.get('Content-Disposition')); console.log('Filename:', filename); const blob = await response.blob(); const url = window.URL.createObjectURL(blob); pdfUrl = url; } else { console.error('Error:', response.statusText); } } catch (error) { console.error('Error:', error); } } /** * @param {string | null} contentDisposition */ function getFilenameFromContentDisposition(contentDisposition) { // @ts-ignore const matches = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/); return matches ? matches[1] : null; } function handleSubmit() { showPDF(); } function navigateToSearch() { goto('/'); }</script><div class="w-full h-full flex justify-center"><div class="w-[90%]"><div class="flex mt-4 justify-center items-center"><!-- Made a form for submitting on enter --><form on:submit|preventDefault={handleSubmit}><div class="group relative"><input class="shadow appearance-none border-2 rounded py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline dark:text-white dark:bg-gray-700" id="username" type="text" placeholder="Enter Plate ID" bind:value={plateID} autocomplete="off" /><div class="hidden group-hover:block absolute dark:bg-gray-600 dark:text-white bg-gray-100 text-gray-700 p-4 rounded-md shadow-md z-10"><p class="relative p-4 bg-gray-200 dark:bg-gray-500 dark:text-white rounded-lg"> To get all daughter plates enter first 7 characters<span class="absolute top-0 left-1/2 -translate-y-1/4 transform -translate-x-1/2 w-5 h-5 dark:bg-gray-500 rotate-45 bg-gray-200" /></p></div></div></form><button class="bg-green-800 hover:bg-green-600 text-white font-bold py-1 px-3 rounded-full disabled:opacity-25 ml-4" on:click={handleSubmit}>Search</button><button class="bg-green-900 hover:bg-green-700 text-white font-bold py-1 px-3 rounded-full ml-6 text-base" on:click={navigateToSearch}>Search By Date</button></div><main class="w-full h-[90%] mt-2"> {#if pdfUrl}<iframe src={pdfUrl} class="w-[95%] h-full mx-auto" style="border: none;" title="PDF" /> {:else}<p>Loading PDF...</p> {/if}</main></div></div>