You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生产环境表单验证错误时CKEditor消失问题(Laravel+Livewire)

Laravel Livewire + CKEditor 验证错误后编辑器消失问题

生产服务器上用Laravel结合Livewire开发的表单集成了CKEditor,提交表单时只要任意字段触发验证错误,CKEditor就会消失,但本地环境(包括用Nginx虚拟主机部署的本地项目)完全没问题,怎么都复现不了这个错误。


HTML表单代码

<form wire:submit.prevent="saveBlog" enctype="multipart/form-data">

    @csrf
    
    <div class="row card-body">
        <div class="col-md-12 col-lg-12 col-sm-12">
            <div class="form-group">
                <label for="blogTitle">Blog Title</label>
                <input type="text" wire:change="convertUrl()" wire:model.defer="state.title" name="blogTitle"  class="form-control @error('title') is-invalid @enderror" id="blogTitle">
                @error('title')
                    <div class="invalid-feedback"> {{$message}} </div>
                @enderror
            </div>
        </div>
        <div class="col-md-12 col-lg-12 col-sm-12">
            <div class="form-group">
                <label for="slug">Blog Custom URL</label>
                <input type="text" wire:model.defer="state.slug" name="slug"  class="form-control @error('slug') is-invalid @enderror" id="slug">
                @error('slug')
                    <div class="invalid-feedback"> {{$message}} </div>
                @enderror
            </div>
        </div>
        <div class="col-md-12 col-lg-12 col-sm-12">
            <div class="form-group">
                <label for="blogTitle">Meta Description</label>
                <input type="text" name="metaDescription" wire:model.defer="state.meta_description"  class="form-control @error('meta_description') is-invalid @enderror" id="metaDescription">
                @error('meta_description')
                    <div class="invalid-feedback">{{$message}}</div>
                @enderror
            </div>
        </div>
        <div class="col-md-12 col-lg-12 col-sm-12">
            <div class="form-group">
                <label for="blogCategory">Category of blog post</label>
                <select id="blogCategory" wire:model.defer="state.blog_cat_id" name="blogCategory" class="form-control @error('blog_cat_id') is-invalid @enderror">
                    <option value="333" selected>Choose Blog Category</option>
                        @foreach($cats as $cat)
                        <option value="{{ $cat->id }}"> {{ $cat->name }} </option>
                        @endforeach
                </select>
                @error('blog_cat_id')
                    <div class="invalid-feedback">{{$message}}</div>
                @enderror
            </div>
        </div>
        <div class="col-md-4 col-lg-4 col-sm-4">
            <div class="form-group">
                <label for="blogThumbnail">Blog Main Image</label>
                <input type="file" class="form-control" wire:model="thumbnail" name="thumbnail" id="thumbnail" accept="image/*">
                @if($thumbnail)
                    <img src="{{$thumbnail->temporaryUrl()}}" class="img-fluid" width="100">
                @endif
                @error('thumnbnail')
                    <div class="invalid-feedback"> {{$message}} </div>
                @enderror
            </div>
        </div>
        <div class="col-md-12 col-lg-12 col-sm-12">
            <div class="form-group" wire:ignore>
                <label for="blogDescription">Blog Detail Description</label>
                <textarea wire:model.defer="state.description" data-description="@this" id="blogDescription" name="blogDescription" class="form-control description"></textarea>
                <div class="text-danger" id="blogDescription_error"></div>
            </div>
        </div>
        <div class="col-md-12 col-lg-12 col-sm-12 text-center">
            <button type="submit" class="btn btn-primary" id="addBlogBtn"><i class="fa fa-comment-o"></i> Submit New Post</button>
        </div>
    </div>
    
    <!-- /.row -->
    
</form>

Livewire组件代码

class CreateBlog extends AdminComponent
{
     public $state = [];
     use WithFileUploads;
     public $thumbnail;
     public $cities;
     public function mount(){
    $this->cities = City::where('active', 1)->get();}

public function render()
{
    $cats = BlogCat::where('active', 1)->get();
    return view('livewire.admin.blogs.create-blog', ['cats' => $cats])->layout('layouts.super-admin');
}

public function saveBlog(){
    //dd($this->thumbnail)
    $data = Validator::make($this->state, [
            'title' => 'required|unique:blogs',
            'blog_cat_id' => 'required|digits_between:0,9',
            'slug' => 'required|unique:blogs',
            'meta_description' => 'required',
            'thumbnail' => 'image|mimes:png,jpg,gif|max:10024',
            'description' => 'required',
    ])->validate();
    $image = $this->thumbnail;
    //$name = Storage::disk('blogs')->put('', $image);
    $img = Image::make($image->getRealPath());
    $img = $img->resize(1000, null, function($constraint){
    $constraint->aspectRatio();
    });
    
    $type = $image->getClientOriginalExtension();
    $data['slug'] = $this->url_title(strtolower($this->state['slug']));
    $name = $data['slug'].'-'.rand(10, 100).'.'.$type;
    Storage::putFileAs(
        'public/blogs', $image, $name);
    $data['thumbnail'] = $name;
    //$slug = $this->url_title(strtolower($data['title']));
    //$data['slug'] = $slug.'-'.rand(5,1000);
    $data['poster_id'] = 1;
    $data['active'] = 1;
    $data['status'] = 1;
    $data['is_commented'] = 0;
    $blog = Blog::create($data);
    if($blog){
        $thumb1 = Image::make($image->getRealPath())->resize(400, 300, function($constraint){
                    $constraint->aspectRatio();
        })->encode('webp', 100);
        $thumb2 = Image::make($image->getRealPath())->resize(400, 300, function($constraint){
                $constraint->aspectRatio();
        })->encode('jpg', 100);
        $name = $this->generateRandomString().time().'.'.'webp';
        $name2 = $this->generateRandomString().time().'.'.'jpg';
        
        Storage::put('public/thumbnail/blog-thumbs/'.$name, $thumb1);
        Storage::put('public/thumbnail/blog-thumbs/'.$name2, $thumb2);
    
        $thumb = new BlogThumb();
        $thumb->blog_id = $blog->id;
        $thumb->name = $name;
        $thumb->jpg_name = $name2;
        $thumb->save();
    }
    if($data['blog_cat_id'] == 7){
        FrontEndController::newsSitemap();
    }else{
        FrontEndController::sitemap();
    }
    
    $this->dispatchBrowserEvent('hide-form', ['message' => 'Blog post added successfully!']);
    return redirect('super-admin/blogs');
}
public function convertUrl(){
    $this->state['slug'] = $this->url_title(strtolower($this->state['title']));
}
public function generateRandomString($length = 10) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}

//Make Slug
public function url_title($str, $separator = '-', $lowercase = FALSE)
{
    if ($separator == 'dash') 
    {
        $separator = '-';
    }
    else if ($separator == 'underscore')
    {
        $separator = '_';
    }
    
    $q_separator = preg_quote($separator);

    $trans = array(
        '&.+?;'                 => '',
        '[^a-z0-9 _-]'          => '',
        '\s+'                   => $separator,
        '('.$q_separator.')+'   => $separator
    );

    $str = strip_tags($str);

    foreach ($trans as $key => $val)
    {
        $str = preg_replace("#".$key."#i", $val, $str);
    }

    if ($lowercase === TRUE)
    {
        $str = strtolower($str);
    }

    return trim($str, $separator);
}

CKEditor初始化代码

<script>
ClassicEditor
  .create(document.querySelector('#blogDescription'), {
    heading: {
      options: [{
          model: 'paragraph',
          title: 'Paragraph',
          class: 'ck-heading_paragraph'
        },
        {
          model: 'heading1',
          view: 'h2',
          title: 'Heading 2',
          class: 'ck-heading_heading2'
        },
        {
          model: 'heading3',
          view: 'h3',
          title: 'Heading 3',
          class: 'ck-heading_heading3'
        },
        {
          model: 'heading4',
          view: 'h4',
          title: 'Heading 4',
          class: 'ck-heading_heading4'
        },

      ]
    },
    // plugins: [SourceEditing],
    // toolbar: ['sourceEditing'],
  })
  .then(editor => {
    // Your code when the editor is ready
    document.querySelector('#addBlogBtn').addEventListener('click', () => {
      let description = $('#blogDescription').data('description');
      eval(description).set('state.description', editor.getData());
    });
  })
  .catch(error => {
    console.error(error);
  });
</script>

内容的提问来源于stack exchange,提问作者ayazBAM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 18:45:54