Livewire 文件上传验证总是第一次失败,但第二次有效

Livewire file upload validation always fails the first time but works the second time

我的 Livewire 有一个奇怪的问题:当我发送文件时,验证总是在第一次失败。如果我的标准是它必须是 pdf,我会放入 PDF,提交表格,收到一条消息告诉我格式错误,我不会更改任何内容,重新提交,它会顺利通过。

有人知道为什么会这样吗?

<?php

namespace App\Http\Livewire\Branch\Documents;

use App\Models\BranchDocument;
use Livewire\Component;
use Livewire\WithFileUploads;

class Upload extends Component
{
    use WithFileUploads;

    public BranchDocument $document;
    public $file;
    public $saved = false;

    public function render()
    {
        return view('livewire.branch.documents.upload');
    }

    public function save() {
        $this->validate([
            'file' => 'mimes:jpg,bmp,png,pdf|max:10240', // 1MB Max
        ]);

        $this->document->file = $this->file;

        $this->saved = true;
    }
}
<div x-data="{ open: false }">
    <li class="@if(!$saved) hover:bg-gray-100  py-2 px-2 rounded cursor-pointer @endif" @click="open = true">
        <div class="relative">
          <div class="relative flex space-x-3">
            <div class="min-w-0 flex-1 flex justify-between space-x-4 items-center">
              <div>
                <p class="text-sm text-porange">{{ $document->document_type->title }}@if($saved)<span class="text-sm text-gray-600"> - {{ __('Document sent!') }}</span>@endif</p>
                <p class="text-xs text-gray-600">{{ $document->created_at->diffForHumans() }}</p>
              </div>
                <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-600" fill="none" viewBox="0 0 24 24" stroke="currentColor" >
                    @if(!$saved)
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" />
                    @else
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
                    @endif
                </svg>
            </div>
          </div>
        </div>
      </li>

      @if(!$saved)
      <div x-show="open" class="fixed z-10 inset-0 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
        <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
          <!--
            Background overlay, show/hide based on modal state.

            Entering: "ease-out duration-300"
              From: "opacity-0"
              To: "opacity-100"
            Leaving: "ease-in duration-200"
              From: "opacity-100"
              To: "opacity-0"
          -->
          <div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>

          <!-- This element is to trick the browser into centering the modal contents. -->
          <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>

          <!--
            Modal panel, show/hide based on modal state.

            Entering: "ease-out duration-300"
              From: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
              To: "opacity-100 translate-y-0 sm:scale-100"
            Leaving: "ease-in duration-200"
              From: "opacity-100 translate-y-0 sm:scale-100"
              To: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
          -->
          <div @click.away="open = false" class="inline-block align-bottom bg-white rounded-lg px-4 py-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6">
            <div>
              <div class="text-center">
                <h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">
                  {{ __('Upload ":title"', ['title' => $document->document_type->title])}}
                </h3>
              </div>
            </div>
            <form wire:submit.prevent="save">

            <input type="file" wire:model="file" class="file-input-business block mx-auto mt-4"/>
            @error('file') <span class="error">{{ $message }}</span> @enderror

            <div class="mt-5 sm:mt-6 sm:grid sm:grid-cols-2 sm:gap-3 sm:grid-flow-row-dense">
              <button type="submit" type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-porange text-base font-medium text-white hover:bg-porange-darker focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-porange sm:col-start-2 sm:text-sm">
                {{ __('Send')}}
              </button>
              <button @click="open = false" type="button" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-porange sm:mt-0 sm:col-start-1 sm:text-sm">
                {{ __('Cancel')}}
              </button>
            </div>
        </form>
          </div>
        </div>
      </div>
      @endif
</div>

谢谢!

文件是否在您点击提交之前上传?如果不是,则文件为空,因此格式错误。验证前在保存方法中检查其值。您还可以在 div 上使用 wire.loading 来确定文件是否仍在上传。

您也可能 运行 遇到内置 artisan 开发服务器(您使用 php artisan serve 命令启动的服务器)的问题。它对 'real' 服务器有不同的限制 - 上传文件大小、格式等。