尝试使用jQuery和ajax提交表单时,我在RouteCollection.php中遇到MethodNotAllowedHttpException

时间:2016-01-14 07:16:54

标签: jquery ajax laravel-5.2

正如在主题中所提到的,当我尝试使用jQuery和ajax提交表单时,我在RouteCollection.php中遇到了一个MethodNotAllowedHttpException

我在routes.php文件中尝试了以下内容

Route::post('/send/', 'CommsController@send');

Route::patch('/send/', 'CommsController@send');

控制器

use App\Http\Controllers\Controller;

class CommsController extends Controller
{
    protected function send(Request $request);
    {
        return response($request);
    }
}

jQuery ajax

if ( isValid ) {
    $( ".validation-summary" ).html( "Sending message..." );

    var data = "";

    data = "message_type=contact"
        + "&first_name=" + first_name.val()
        + "&last_name=" + last_name.val()
        + "&email=" + email.val()
        + "&message=" + message.val()

    $.ajax({
        type: "post",
        url: "send",
        data: data,
        error: function( response ) {
            $( ".validation-summary" ).removeClass( "success" );
            $( ".validation-summary" ).addClass( "validation-summary error" );
            $( ".validation-summary" ).html( "Error" );
        },
        success: function() {
            $( ".validation-summary" ).html( "Message sent." );
        }               
    });
    return false;
} else {
    return false;
}

感谢。

5 个答案:

答案 0 :(得分:0)

在Laravel 5.2中,您需要在web中间件中设置路由,我假设您已将post路由放在中间件中:

Route::group(['middleware' => ['web']], function() {

    Route::post('/send', 'YourController@methodName');

});

如果我在你的位置,我会做一些其他事情,虽然类似于你的代码正在做的事情。

<强>的jQuery

(function() {
    // replace $('.btnSubmit') with whatever you want
    $('.btnSubmit').click(function(e) {
        var form       = $('#yourFormId'),
            postAction = form.attr('action'),
            postData   = form.serialize();

        $.ajax({
            type: 'POST',
            url: postAction,
            data: postData,
            success: function(res) {
                console.log(res);
            },
            error: function(res) {
                console.log('Error:' + res);
            }
        });

        return false;
    });
})();

我做了什么:

  1. 直接在表单中放置action参数,而不是在jQuery AJAX中定义它
  2. 序列化表单的输入值并发布相同的
  3. 使用自我调用匿名函数
  4. 只是旁注:

    您重复$('.validation-summary') 5次。这意味着您违反了不推荐的Principles of DRY。解决方案:

    var valSum = $('.validation-summary');
    

    然后你可以在那段代码中使用n次。

    希望这会帮助你。快乐的编码。欢呼声。

答案 1 :(得分:0)

尝试发布&#39;而不是发布&#39;在你的routes.php和你的ajax电话中。有同样的问题,这就解决了我。希望它有所帮助。

答案 2 :(得分:0)

根据您对csrf_token最佳解决方案(IMO)的最新评论:

将以下行添加到<head></head>内:

<meta id="csrf_token" name="csrf_token" content="{{ csrf_token() }}">

然后添加以下js:

$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf_token"]').attr('content')
    }
});

这意味着csrf会自动包含在您的ajax调用中。

或者,您可以获取_token的值并将其包含在数据变量中,如下所示:

data = "message_type=contact"
    + "&first_name=" + first_name.val()
    + "&last_name=" + last_name.val()
    + "&email=" + email.val()
    + "&message=" + message.val()
    + "&_token=" + $("input[name=_token]").val();

希望这有帮助!

答案 3 :(得分:0)

更新:我的routes.php文件

Route::post('/send', 'CommsController@send');

控制器

public function send(Request $request)
{
    // return view('contact.contact');
    return view('contact.contact')->with('data', json_encode($request));
}

app / Http / Middleware / VerifyCsrfToken.php //可能没有必要加入VerifyCsrfToken.php,但不太确定

protected function tokensMatch($request) {
    // If request is an ajax request, then check to see if token matches token provider in
    // the header. This way, we can use CSRF protection in ajax requests also.
    $token = $request->ajax() ? $request->header('X-CSRF-Token') : $request->input('_token');

    return $request->session()->token() == $token;
}

jQuery ajax

<head>
    <meta id="csrf_token" name="csrf_token" content="{{ csrf_token() }}">
</head>

$( document ).ready(function() {
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });

    ....

    $.ajax({
        type: "POST",
        url: postAction,
        data: JSON.stringify(postData),
        dataType: 'json',
        encode: true
    }).done(function(response) {
        // log data to the console so we can see
        console.log(response); 

        // here we will handle errors and validation messages
        if ( ! response.success ) {
            valSum.removeClass( "success" );
            valSum.addClass( "validation-summary error" );
            valSum.html( response.errors );
        } else {
            // $( ".validation-summary" ).html( "Message sent." );
            valSum.html( response.message );
        }
    })
    .fail(function(response) {
        valSum.removeClass( "success" );
        valSum.addClass( "validation-summary error" );
        valSum.html( "Server Error: " + response.statusText + " processing your request, please contact Dorothea or report a bug." );
    });

我的浏览器已返回网络错误

500 (Internal Server Error)

php_error.log文件条目

local.ERROR: Illuminate\Session\TokenMismatchException in C:\cx\laravel\dorothea\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php:67

答案 4 :(得分:0)

您好@ user3514160我只是想通过更改post方法获取方法让您知道我解决了我的问题。不太清楚为什么get工作但是帖子不是,但至少目前问题已经解决了。

如果有人能够阐明为什么会出现这种情况会很棒。