LARAVEL - 使用 Route::resource 生成路由时无法使用销毁路由

LARAVEL - Unable to use destroy route when generating it with Route::resource

上下文。我在 Laravel 8 工作,我使用 DataTables 插件显示数据库中的记录。正如您将在代码中看到的那样,我创建了所有用于执行 CRUD 的路由:Route::resource('animal', 'AnimalController')。这会为 DESTROY 方法生成一个路径,如下所示:animal/{id}

问题。当我按下特定记录的删除按钮时,记录被删除了,很好,但是浏览器控制台 returns 出现此错误:“此路由不支持 DELETE 方法。支持的方法:GET、HEAD、POST",因此 Javascript 被破坏,记录被删除的警告永远不会显示。如果我将请求类型更改为 POST 而不是 DELETE,错误会告诉我不支持 POST 而 DELETE 是!

问题:我做错了什么?

路线

Route::resource('animal', 'AnimalController');

CONTROLLER 打印数据表

public function index(Request $request)
{
    if($request->ajax()) {
        $animals = DB::select('CALL sp_select_animal()');
        return DataTables::of($animals)
            ->addIndexColumn()
            ->addColumn('action', function($animals){
                $actions  = '<a href="" class="btn btn-info btn-sm">Edit</a>';
                $actions .= '<button type="button" id="'.$animals->id.'" data-name="'.$animals->name.'" name="delete" class="btn btn-danger btn-sm ml-1 delete">Delete</button>';
                return $actions;
            })
            ->rawColumns(['action'])
            ->make(true);
    }
    return view('animal.index');
}

控制器删除记录

public function destroy($id)
{
    $animal = DB::select('CALL sp_destroy_animal(?)', [$id]);
    return back();
}

VIEW

jQuery('#BTNdelete').click(function(e){
    e.preventDefault();
    var url = '{{ route("animal.destroy", ":xxx") }}';
    url = url.replace(':xxx', animalID);
    jQuery.ajax({
        "url": url,
        "type": 'DELETE',
        "data": {
            "_token": "{{ csrf_token() }}"
        },
        success: function(data) {
            setTimeout(function() {
                jQuery('#modal').modal('hide');
                toastr.warning('The record was successfully deleted', 'Delete Record', {timeOut:3000});
                jQuery('#tableAnimal').DataTable().ajax.reload();
            }, 100);
        }
    });
});

现在,如果我创建一个特定的删除记录的路径,一切正常,例如

Route::get('animal/delete/{id}', [AnimalController::class, 'destroy'])->name('animal.destroy')

这将解决问题。但我不想创建额外的路线。我想使用通过 resource() 方法生成的路由。

JavaScript中有很多问题,但问题的根源是浏览器无法发出 DELETE 请求,因此它们必须 fake them

// bind to the class of the button, not a non-existent ID
jQuery('button.delete').click(function(e) {
    // this isn't really needed, a button has no default action
    e.preventDefault();
    // you do want to stop the event from bubbling though
    e.stopPropagation();
    // this properly escapes the value for JavaScript, not HTML
    var url = @json(route("animal.destroy", ":xxx"));
    // WHAT IS animalID ???
    url = url.replace(':xxx', animalID);
    // build the post request with the fake method added
    jQuery.post(
        url,
        {_token: @json(csrf_token()), _method: "DELETE"},
        function(data) {
            setTimeout(function() {
                jQuery('#modal').modal('hide');
                toastr.warning('The record was successfully deleted', 'Delete Record', {timeOut:3000});
                jQuery('#tableAnimal').DataTable().ajax.reload();
            }, 100);
        }
    );
});

但必须指出,您的控制器的 index() 方法不应该处理 HTML;那完全是视图的工作。仅向其提供构建 HTML 所需的数据。这可以完成 using column.render. See 作为示例。