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

Posted

技术标签:

【中文标题】LARAVEL - 使用 Route::resource 生成路由时无法使用销毁路由【英文标题】:LARAVEL - Unable to use destroy route when generating it with Route::resource 【发布时间】:2021-02-18 17:20:12 【问题描述】:

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

问题。当我按下特定记录的删除按钮时,记录被删除,很好,但浏览器控制台返回此错误:“此路由不支持 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');

CONTROLLER 删除记录

public function destroy($id)

    $animal = DB::select('CALL sp_destroy_animal(?)', [$id]);
    return back();

查看

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()方法生成的路由。

【问题讨论】:

【参考方案1】:

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 完成。示例见this question。

【讨论】:

以上是关于LARAVEL - 使用 Route::resource 生成路由时无法使用销毁路由的主要内容,如果未能解决你的问题,请参考以下文章

使用 laravel 安装程序创建 laravel 项目

Laravel快速使用Elasticsearch

laravel和mongo怎么搭配使用

Laravel 使用外部类

Laravel + React,使用 Laravel 身份验证的 api

win 怎么laravel命令