【问题标题】:401 Unauthorized DELETE request to RESTful API in laravel via Ajax401 通过 Ajax 在 laravel 中对 RESTful API 的未经授权的 DELETE 请求
【发布时间】:2015-07-06 02:49:56
【问题描述】:

我使用 laravel 控制器创建了一个 RESTful API。我有一个PhotosController,它有一个destroy($id) 删除资源的方法。我还有一段 javascript 代码向我的应用程序发送 DELETE 请求。结果应该是删除带有$id id 的照片。但是 laravel 不会将我的请求路由到 destroy 方法。而是发送 401 Unauthorized 错误。

问题是我想通过Ajax 向我的应用发送DELETE 请求,但是laravel 不允许我的请求被路由!

routes.php 文件:

Route::resource('photos', 'PhotosController');

销毁方法:

public function destroy($id)
{
    try{
        unlink($_SERVER["DOCUMENT_ROOT"].'/uploads/doctors/' . $id);
        Session::forget('photo');
        $msg = Notification::where('flag', 's')->where('code', 'user-update-delete-photo-gallery')->first()->msg;
        return Response::json(array('success' => $msg));
    }catch (Exception $e){
        App::abort(500, $e->getMessage());
    }
}

我的 Ajax 请求:

$.ajax(
    {
        url: "/photos/" + name,
        method : "DELETE", // Or POST : result is the same
        data :{
            _token : $("input[name=_token]").val(),
            _method : 'DELETE'
        },
        success: function(data, textStatus, jqXHR ){
            parent.replaceWith("");
            toastr.success(data['success']);
            $("#overlay").hide();
        },
        beforeSend : function(jqXHR, settings ){
            $("#overlay").show();
        },
        error : function(jqXHR, textStatus, errorThrown ){
            toastr.error(jqXHR.responseText);
            $("#overlay").hide();
        }
    }
);

感谢您的帮助。

【问题讨论】:

  • 可能是因为请求使用了method : "DELETE"。我认为该应用程序可能正在等待 POST。数据数组中的_method : 'DELETE' 不是应该处理这个问题吗?
  • @Don'tPanic 感谢您的参与。我用过POST,但结果是一样的。
  • 还有一点,资源控制器方法名不是需要在HTTP方法前加前缀吗?
  • @Don'tPanic 不,在 Laravel 4.2 中没有必要这样做。看看Laravel Documentation
  • 你确定吗?我只是在看here,特别是。它说“接下来,只需将方法添加到您的控制器,以它们响应的 HTTP 动词为前缀:”

标签: php jquery ajax rest laravel


【解决方案1】:

我认为您的系统需要对控制器操作“销毁”方法进行身份验证。所以你需要在调用该方法之前登录。

如果您使用的是中间件“auth”(app\Http\Middleware\Authenticate.php),您可以轻松找到返回“Unauthorized”错误的“handle”函数。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    我一直在我的 Laravel 应用程序中做这种事情,没有任何问题。此代码允许用户通过 AJAX 删除资源,同时首先显示引导确认对话框。代码按事件发生的顺序排列。

    查看资源以删除

    <a class="delete-plan" href="{{ route('admin.plans.destroy', $plan['id']) }}" data-redirect="{{ route('admin.plans.index') }}" data-plan-name="{{ $plan['name'] }}" data-lang="billing.plans">
        <i class="fa fa-trash fa-lg"></i>
    </a>
    

    JQUERY 提示确认模式

    $('.delete-plan').on('click', function(e) {
        e.preventDefault();
    
        var data = {
            'route':        $(this).attr('href'),
            'redirect':     $(this).data('redirect'),
            'modal_title':  'Delete Plan',
            'content_view': 'Are you sure you want to delete plan: <strong>' + $(this).data('plan-name') + '</strong>?',
            'lang':         $(this).data('lang')
        };
    
        loadDestroyModal(data);
    });
    
    function loadDestroyModal(data) {
        $.get('/ajax/destroy-modal', { data: data }, function(modal) {
            $('body').append(modal);
            $('#destroy-modal').modal('show');
        });
    }
    

    AJAX 控制器

    // routed by /ajax/destroy-modal
    public function destroyModal() {
        $data = Input::get('data');
    
        $params = [
            'route'    => $data['route'],
            'redirect' => $data['redirect'],
            'title'    => $data['modal_title'],
            'content'  => $data['content_view'],
            'lang'     => $data['lang']
        ];
    
        return View::make('_helpers.modal-destroy', $params);
    }
    

    销毁确认模式(_helpers.modal-destroy)

    <div id="destroy-modal" class="modal fade">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal">
                        <span aria-hidden="true"><i class="fa fa-times"></i></span>
                        <span class="sr-only">Close</span>
                    </button>
                    <h4 class="modal-title">{{ $title }}</h4>
                </div>
                <div class="modal-body">
                    {{ $content }}
                </div>
                <div class="modal-footer">
                    <button id="modal-confirm" type="button" class="btn btn-primary" data-route="{{ $route }}"
                    data-redirect="{{ $redirect }}" data-lang="{{ $lang }}">Confirm</button>
                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>
    

    JQUERY 处理销毁方法并重定向 FLASH 消息

    $('body').on('click', '#destroy-modal #modal-confirm', function(e) {
        var redirect = $(this).data('redirect');
        var lang     = $(this).data('lang');
    
        $(this).html('<i class="fa fa-spinner fa-spin"></i> Please Wait');
    
        $.ajax({
            'url':     $(this).data('route'),
            'type':    'DELETE',
            'success': function(response) {
                if (response) {
                    redirectWithFlashMessage(redirect, 'destroy', 'success', lang);
                } else {
                    redirectWithFlashMessage(redirect, 'destroy', 'errors', lang);
                }
            }
        });
    });
    

    计划控制器

    public function destroy($id)
    {
        try
        {
            Stripe::plans()->destroy(['id' => $id]);
    
            return Response::json(TRUE);
        }
        catch (Exception $e)
        {
            return Response::json(FALSE);
        }
    }
    

    用于重定向的 JQUERY

    function redirectWithFlashMessage(redirect, type, status, lang) {
        var params = {
            type:   type,
            status: status,
            lang:   lang
        };
    
        $.get('/ajax/flash', params, function(response) {
            window.location.href = redirect;
        });
    }
    

    AJAX 控制器(使用 Flash 重定向)

    public function flashData() {
        $message_type = 'success' == Input::get('status') ? 'success' : 'failure';
    
        $message = Lang::get(Input::get('lang'))[Input::get('type') . '_' . $message_type];
    
        Session::flash($message_type, $message);
    
        return ['status' => $message_type, 'message' => $message];
    }
    

    这是很多代码,但是一旦设置它就非常容易复制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-17
      • 1970-01-01
      • 1970-01-01
      • 2018-10-23
      • 1970-01-01
      • 1970-01-01
      • 2018-10-08
      • 2021-12-19
      相关资源
      最近更新 更多