Загрузка файла в реакции и laravel

Итак, я пытаюсь загрузить PDF-файл, который хранится в моем каталоге загрузок в общей папке. Я использую интерфейс React и серверную часть Laravel. Вот как я обрабатываю логику во внешнем интерфейсе

const downloadFile = async (attachmentName) => {
        try {
            const response = await fetch(`/attachments/${attachmentName}`);
            
            // Check if the response is OK
            if (!response.ok) {
                throw new Error(`Failed to download file: ${response.status} ${response.statusText}`);
            }
            
            // Create a blob URL for the file content
            const url = window.URL.createObjectURL(await response.blob());
            
            // Create a temporary link element to trigger the download
            const link = document.createElement('a');
            link.href = url;
            link.setAttribute('download', attachmentName);
            
            // Append the link to the document body and trigger the download
            document.body.appendChild(link);
            link.click();
            
            // Clean up
            document.body.removeChild(link);
            window.URL.revokeObjectURL(url);
        } catch (error) {
            console.error('Error downloading attachment:', error);
        }
    }
//Some more Code

<a href = "#" onClick = {() => downloadFile(job.attachments)}>
                             
    <svg xmlns = "http://www.w3.org/2000/svg" width = "16" height = "16" fill = "#b72424" class = "bi bi-file-earmark-pdf-fill" viewBox = "0 0 16 16">
        <path d = "M5.523 12.424q.21-.124.459-.238a8 8 0 0 1-.45.606c-.28.337-.498.516-.635.572l-.035.012a.3.3 0 0 1-.026-.044c-.056-.11-.054-.216.04-.36.106-.165.319-.354.647-.548m2.455-1.647q-.178.037-.356.078a21 21 0 0 0 .5-1.05 12 12 0 0 0 .51.858q-.326.048-.654.114m2.525.939a4 4 0 0 1-.435-.41q.344.007.612.054c.317.057.466.147.518.209a.1.1 0 0 1 .026.064.44.44 0 0 1-.06.2.3.3 0 0 1-.094.124.1.1 0 0 1-.069.015c-.09-.003-.258-.066-.498-.256M8.278 6.97c-.04.244-.108.524-.2.829a5 5 0 0 1-.089-.346c-.076-.353-.087-.63-.046-.822.038-.177.11-.248.196-.283a.5.5 0 0 1 .145-.04c.013.03.028.092.032.198q.008.183-.038.465z"/>
        <path fill-rule = "evenodd" d = "M4 0h5.293A1 1 0 0 1 10 .293L13.707 4a1 1 0 0 1 .293.707V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2m5.5 1.5v2a1 1 0 0 0 1 1h2zM4.165 13.668c.09.18.23.343.438.419.207.075.412.04.58-.03.318-.13.635-.436.926-.786.333-.401.683-.927 1.021-1.51a11.7 11.7 0 0 1 1.997-.406c.3.383.61.713.91.95.28.22.603.403.934.417a.86.86 0 0 0 .51-.138c.155-.101.27-.247.354-.416.09-.181.145-.37.138-.563a.84.84 0 0 0-.2-.518c-.226-.27-.596-.4-.96-.465a5.8 5.8 0 0 0-1.335-.05 11 11 0 0 1-.98-1.686c.25-.66.437-1.284.52-1.794.036-.218.055-.426.048-.614a1.24 1.24 0 0 0-.127-.538.7.7 0 0 0-.477-.365c-.202-.043-.41 0-.601.077-.377.15-.576.47-.651.823-.073.34-.04.736.046 1.136.088.406.238.848.43 1.295a20 20 0 0 1-1.062 2.227 7.7 7.7 0 0 0-1.482.645c-.37.22-.699.48-.897.787-.21.326-.275.714-.08 1.103"/>
    </svg>

                             
    {getAttachmentName(job.attachments)}
</a>

И вот моя внутренняя логика Файл маршрутов

Route::get('/attachments/{attachment}', [AttachmentController::class, 'show'])->name('attachments.show');

Контроллер

{
    public function show($attachment)
    {
        // Check if the file exists
        if (!Storage::disk('public')->exists($attachment)) {
            abort(404); // Or return a suitable error response
        }

        // Retrieve the file contents
        $fileContents = Storage::disk('public')->get($attachment);

        // Return the file as a response with the appropriate headers
        return response($fileContents, 200)
            ->header('Content-Type', 'application/pdf')
            ->header('Content-Disposition', 'attachment; filename = "' . basename($attachment) . '"');
    }
    
}

Так почему-то. При загрузке файл загружается, но файл поврежден. Кроме того, он не содержит даже близкого общего количества байтов, которое он должен содержать.

Так в чем же может быть проблема?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Более заметным может быть добавление атрибута download к anchor.

<a href = "/attachments/${job.attachments}" download = {true}>
    <svg xmlns = "http://www.w3.org/2000/svg" width = "16" height = "16" fill = "#b72424" class = "bi bi-file-earmark-pdf-fill" viewBox = "0 0 16 16">
        <path d = "M5.523 12.424q.21-.124.459-.238a8 8 0 0 1-.45.606c-.28.337-.498.516-.635.572l-.035.012a.3.3 0 0 1-.026-.044c-.056-.11-.054-.216.04-.36.106-.165.319-.354.647-.548m2.455-1.647q-.178.037-.356.078a21 21 0 0 0 .5-1.05 12 12 0 0 0 .51.858q-.326.048-.654.114m2.525.939a4 4 0 0 1-.435-.41q.344.007.612.054c.317.057.466.147.518.209a.1.1 0 0 1 .026.064.44.44 0 0 1-.06.2.3.3 0 0 1-.094.124.1.1 0 0 1-.069.015c-.09-.003-.258-.066-.498-.256M8.278 6.97c-.04.244-.108.524-.2.829a5 5 0 0 1-.089-.346c-.076-.353-.087-.63-.046-.822.038-.177.11-.248.196-.283a.5.5 0 0 1 .145-.04c.013.03.028.092.032.198q.008.183-.038.465z"/>
        <path fill-rule = "evenodd" d = "M4 0h5.293A1 1 0 0 1 10 .293L13.707 4a1 1 0 0 1 .293.707V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2m5.5 1.5v2a1 1 0 0 0 1 1h2zM4.165 13.668c.09.18.23.343.438.419.207.075.412.04.58-.03.318-.13.635-.436.926-.786.333-.401.683-.927 1.021-1.51a11.7 11.7 0 0 1 1.997-.406c.3.383.61.713.91.95.28.22.603.403.934.417a.86.86 0 0 0 .51-.138c.155-.101.27-.247.354-.416.09-.181.145-.37.138-.563a.84.84 0 0 0-.2-.518c-.226-.27-.596-.4-.96-.465a5.8 5.8 0 0 0-1.335-.05 11 11 0 0 1-.98-1.686c.25-.66.437-1.284.52-1.794.036-.218.055-.426.048-.614a1.24 1.24 0 0 0-.127-.538.7.7 0 0 0-.477-.365c-.202-.043-.41 0-.601.077-.377.15-.576.47-.651.823-.073.34-.04.736.046 1.136.088.406.238.848.43 1.295a20 20 0 0 1-1.062 2.227 7.7 7.7 0 0 0-1.482.645c-.37.22-.699.48-.897.787-.21.326-.275.714-.08 1.103"/>
    </svg>
    
    {getAttachmentName(job.attachments)}
</a>

Атрибут download предотвратит перезагрузку браузера.

Если атрибут download не работает, вместо него можно использовать target = "_blank".

Ответ принят как подходящий

Я предполагаю, что проблема в том, как я обрабатывал запрос во внешнем интерфейсе. Потому что это не затрагивало серверную часть. Поскольку я не использовал axiosClient. Я также добавил функцию removeUploadsPrefix, чтобы удалить префикс «uploads/» из имени файла, поскольку он вызывал ошибку.

const removeUploadsPrefix = (fileName) => {
   return fileName.replace(/^uploads//, '');
};    
const downloadFile = async (attachmentName) => {
        attachmentName = removeUploadsPrefix(attachmentName);
      
        try {
          setLoading(true);
          const response = await axiosClient.get(`/attachments/${attachmentName}`, {
            responseType: 'blob',
          });
      
          // Check if the response status is 200 (OK)
          if (response.status !== 200) {
            throw new Error(`Failed to download file: ${response.status} ${response.statusText}`);
          }
      
          // Create a link to download the file
          const url = window.URL.createObjectURL(new Blob([response.data]));
          const link = document.createElement('a');
          link.href = url;
          link.setAttribute('download', attachmentName); // or use a custom file name
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
      
          console.info('Download successful');
        } catch (error) {
          console.error('Error downloading file:', error);
          setErrors('Failed to download file');
        } finally {
          setLoading(false);
        }
      };

А затем на бэкэнде я снова добавляю префикс «uploads/».

    public function show($attachment)
    {
        // Adjust the attachment path to include the 'uploads/' directory
        $attachmentPath = 'uploads/' . $attachment;

        // Log the attachment path
        \Log::info('Attempting to retrieve attachment:', ['attachment' => $attachmentPath]);

        // Check if the file exists
        if (!Storage::disk('public')->exists($attachmentPath)) {
            \Log::error('File not found:', ['attachment' => $attachmentPath]);
            abort(404, 'File not found'); // Or return a suitable error response
        }

        // Retrieve the file contents
        $fileContents = Storage::disk('public')->get($attachmentPath);

        // Return the file as a response with the appropriate headers
        return response($fileContents, 200)
            ->header('Content-Type', 'application/pdf')
            ->header('Content-Disposition', 'attachment; filename = "' . basename($attachmentPath) . '"');
    }

Другие вопросы по теме