【问题标题】:LARAVEL - Unable to use destroy route when generating it with Route::resourceLARAVEL - 使用 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()方法生成的路由。

【问题讨论】:

    标签: php laravel laravel-routing


    【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-07
      • 2018-02-17
      • 1970-01-01
      • 2022-01-25
      • 2015-08-12
      • 1970-01-01
      • 1970-01-01
      • 2018-12-19
      相关资源
      最近更新 更多