Laravel路由方法调用适用于闭包函数,但不适用于Controller @方法

时间:2015-04-18 00:54:03

标签: laravel laravel-4 laravel-routing

有什么区别:

Route::post('insert/{slug}/{page_number}/{person_type_id}/{user_id}', function($slug) {
    return Response::json(
    [
        'success' => false,
        'slug' => $slug
    ]);
});

和此:

Route::post(
  '{slug}/users/page/{page_number}/insert-ben/{person_type_id}/user/{user_id}',
  'PersonsController@insertBen'
);

第一个有效。后者曾经工作但现在不再工作了。我尝试单步执行代码,后者最终转到UsersController@login而不是PersonsConroller@insertBen。太奇怪了。这个工作大约一个月前。我正试着看看我用我的版本控制改变了什么,但它太奇怪了,它不会突然工作。

我的帖子工作正常,因为我可以登录,并且正在调用UsersController@doLogin的帖子。

我甚至测试了这个电话:

Route::post(
  '{slug}/users/page/{page_number}/insert-ben/{person_type_id}/user/{user_id}',
  'UsersController@insertTest'
);

/controllers/UsersController.php

public function insertTest($slug)
{
    if ( Request::ajax() ) {
        return Response::json( [

            'success' => false,
            'slug'      => $slug

        ] );
    }
}

PersonsController@insertBen不起作用。我的PersonsController工作正常,因为我可以使用此控制器进行更新。那可能是什么问题呢?有人遇到类似的东西?为什么route.php会调用某些Controller@method上的帖子而不会调查其他帖子?为什么闭包函数有效但不是Controller@method

更新

这是整个文件。我甚至通过将该行放在靠近文件顶部的位置进行测试。

/** ------------------------------------------
 *  Route binding
 *  ------------------------------------------
 */
App::bind('Acme\Repositories\Interfaces\IPersonRepository', 'Acme\Repositories\Person\DbPersonRepository');
App::bind('Acme\Repositories\Interfaces\IUserRepository', 'Acme\Repositories\User\DbUserRepository');
App::bind('Acme\Repositories\Interfaces\IPage15Repository', 'Acme\Repositories\Pages\Page15Repository');

/** ------------------------------------------
 *  Route model binding
 *  ------------------------------------------
 */
Route::model('user', 'User');
Route::model('comment', 'Comment');
Route::model('post', 'Post');
Route::model('role', 'Role');

/** ------------------------------------------
 *  Route constraint patterns
 *  ------------------------------------------
 */
Route::pattern('comment', '[0-9]+');
Route::pattern('post', '[0-9]+');
Route::pattern('user', '[0-9]+');
Route::pattern('role', '[0-9]+');
Route::pattern('token', '[0-9a-z]+');


/** ------------------------------------------
 *  Admin Routes
 *  ------------------------------------------
 */
Route::group(array('prefix' => 'admin', 'before' => 'auth'), function()
{
    # User Management

    Route::get('users/', ['as' => 'admin.users.get.index', 'uses' => 'AdminUsersController@getIndex']);
    Route::get('users/index', ['as' => 'admin.users.get.index_page', 'uses' => 'AdminUsersController@getIndex']);
    Route::get('users/data', ['as' => 'admin.users.get.data', 'uses' => 'AdminUsersController@getData']);
    Route::get('users/{user}/edit_user_by_page/{page_number}', ['as' => 'admin.users.get.edit_user_by_page', 'uses' => 'AdminUsersController@getEditUserByPage']);

    # Admin Dashboard
    Route::get('/', 'AdminDashboardController@getIndex' );
});

// Confide routes
Route::get('users/create', ['as' => 'confide.users.get.create', 'uses' => 'UsersController@create']);
Route::post('users', ['as' => 'confide.users.post.store', 'uses' => 'UsersController@store']);
Route::get('users/login', ['as' => 'confide.users.get.login', 'uses' => 'UsersController@login']);
Route::post('users/login', ['as' => 'users.login', 'uses' => 'UsersController@doLogin']);
Route::get('users/confirm/{code}', ['as' => 'confide.users.get.confirm', 'uses' => 'UsersController@confirm']);
Route::get('users/forgot_password', [ 'as' => 'users.forgot_password', 'uses' => 'UsersController@forgotPassword' ]);
Route::post('users/forgot_password', ['as' => 'confide.users.post.forgot_password', 'uses' => 'UsersController@doForgotPassword']);
Route::get('users/reset_password/{token}', ['as' => 'confide.users.get.reset_password', 'uses' => 'UsersController@resetPassword']);
Route::post('users/reset_password', ['as' => 'confide.users.post.reset_password', 'uses' => 'UsersController@doResetPassword']);
Route::get('users/resendconfirmationemail', [ 'as' => 'users.resendconfirmationemail', 'uses' => 'UsersController@getResendConfirmationEmail' ]);
Route::post('users/resendconfirmationemail', ['as' => 'confide.users.post.resendconfirmationemail', 'uses' => 'UsersController@postResendConfirmationEmail']);
Route::get('users/logout', ['as' => 'confide.users.get.logout', 'uses' => 'UsersController@logout'])->after('invalidate-browser-cache');

/** ------------------------------------------
 *  Frontend Routes
 *  ------------------------------------------
 */

Route::get('{slug}/users/page', ['as' => 'users.page.path', 'uses' => 'UsersController@getPage'])->where('slug', '^\b(ir){0,1}(revocable){1}\b$');

//get page_number
Route::get('{slug}/users/page/{page_number}', ['before' => 'auth', 'as' => 'users.page.page_number', 'uses' => 'PersonsController@index'])->where('slug', '^\b(ir){0,1}(revocable){1}\b$');

//get edit
Route::get('{slug}/users/page/{page_number}/edit', ['before' => ['auth', 'slug' ], 'as' => 'users.page.page_number.edit', 'uses' => 'PersonsController@edit'])->where('slug', '^\b(ir){0,1}(revocable){1}\b$');

//post insert-ben
Route::post('{slug}/users/page/{page_number}/insert-ben/{person_type_id}/user/{user_id}', ['before' => 'auth', 'as' => 'users.page.page_number.insert', 'uses' => 'PersonsController@insertBen'])->where('slug', '^\b(ir){0,1}(revocable){1}\b$');

//post delete-ben
Route::post('{slug}/users/page/{page_number}/delete-ben/{person_type_id}/user/{user_id}/person_id/{person_id}/address_id/{address_id}/ben_id/{ben_id}', ['before' => 'auth', 'as' => 'users.page.page_number.delete', 'uses' => 'PersonsController@deleteBen'])->where('slug', '^\b(ir){0,1}(revocable){1}\b$');

//put update
Route::put('{slug}/users/page/{page_number}/update', ['before' => 'auth', 'as' => 'users.page.page_number.update', 'uses' => 'PersonsController@update'])->where('slug', '^\b(ir){0,1}(revocable){1}\b$');

//get upgrade page when user goes to a page like (page 17 or other pages like page 9 and 10 I think) reserved only for irrevocable registered plans. TODO: get the upgrade View model
Route::get('{slug}/users/upgrade/{_meta}', [ 'as' => 'users.ugprade', 'uses' => 'PersonsController@upgrade' ] )->where('slug', '^\b(irrevocable){1}\b$');

//Paypal post Paypal info to tables paypals, paypal_transactions, pricings and getPaypalBtn
Route::put('paypal_transactions/{slug}/{page_number}/returnpaypalbtn', ['before' => 'auth', 'as' => 'paypal_transactions.returnpaypalbtn', 'uses' => 'PaypalTransactionsController@returnPaypalBtn'])->where('slug', '^\b(ir){0,1}(revocable){1}\b$');

/** ------------------------------------------
 * Tests:
 * ------------------------------------------
 */
Route::get('users/{username}/page', ['as' => 'users.page.test', 'uses' => 'UsersController@getPageTest']);
Route::get('{slug}/users/show_sql', ['as' => 'users.page.show_sql', 'uses' => 'PersonsController@showSql'])->where('slug', '^\b(ir){0,1}(revocable){1}\b$');

# Index Page - Last route, no matches
Route::get('/', array('before' => 'detectLang', 'uses' => 'UsersController@login'));

1 个答案:

答案 0 :(得分:0)

男孩,这花了很长时间才弄明白。感谢上帝!发生了什么事,我在Route::filter('csrf', function()中有这条线。 此过滤器会在您的其他Route::[method]之前调用,因此,如果您的过滤器中有任何Route次调用,就像我在我的调用中那样,那么您定义的Route::[method]将被调用。我认为默认情况下并非100%确定:

/app/filters.php

$token = Request::ajax() ? ( Request::header('X-CSRF-Token')  ) : Input::get('_token');

我最终来自http://words.weareloring.com/development/laravel/laravel-4-csrf-tokens-when-using-jquerys-ajax/

这是一个ajax调用,但此Request::header('X-CSRF-Token')始终是null

所以我把它改成了更具可读性的东西。

if ( Request::ajax() )
{
    $sRequestHeaderCSRF = Request::header('X-CSRF-Token');
    if ( Request::header('X-CSRF-Token') === null || Request::header('X-CSRF-Token') === '' )
    {
        $token = Input::get('_token');
    } else
    {
        $token = Request::header('X-CSRF-Token');
    }
} else
{
    $token = Input::get('_token');
}

另一个障碍是这个Input::get('_token'),它也返回了null。

我必须通过并明确地命名_token中的data。以前我是 将序列化数组作为data传递给jQuery $.ajax。但呼吁 从_token中的data获取public function input($key = null, $default = null)密钥名称 (见下文)没有从序列化数组中检索它;因此,显式键被传递为 '_token': oSerializeArray._token

var oSerializeArray['_token'] = $('input[name="_token"]').val();

$.ajax({
        type: action,
        cache: false,
        dataType: 'json',
        url: sUrl,
        data: {
            'oSerializeArray':  oSerializeArray,
            '_token': oSerializeArray._token
        },
        beforeSend: function() {
        }
    })
        .done( function( data, text, jqxhr ) {
            data.success;
            //data.iPersonsPK;
            window.location.replace(sUrlEdit);
        })
        .fail( function ( data, jqxhr ) {
            data.success;
        })
        .always( function ( data ) {
            data.success;
        });

只是fyi,Input::get('_token')来自:

/vendor/illuminate/support/Illuminate/Support/Facades/Input.php

在这个函数中:

public static function get($key = null, $default = null)
    {
        return static::$app['request']->input($key, $default);
    }

在这里:

/vendor/laravel/framework/src/Illuminate/Http/Request.php:248

在这个函数中:

public function input($key = null, $default = null)
    {
        $input = $this->getInputSource()->all() + $this->query->all();

        return array_get($input, $key, $default);
    }

我不得不单步执行代码。

这是我更新的Route::filter('csrf', function()

Route::filter('csrf', function()
{
    if ( Request::ajax() )
    {
        $sRequestHeaderCSRF = Request::header('X-CSRF-Token');
        if ( Request::header('X-CSRF-Token') === null || Request::header('X-CSRF-Token') === '' )
        {
            $token = Input::get('_token');
        } else
        {
            $token = Request::header('X-CSRF-Token');
        }
    } else
    {
        $token = Input::get('_token');
    }

    $sSessionToken = Session::token();

//if the tokens do not match then send to the login page
    if (Session::token() != $token) {
        return Redirect::to( 'users/login' );
    }
});

此外,对于您的routes.php问题,更多的问题可能会查看这些文件:

/vendor/laravel/framework/src/Illuminate/Routing/Router.php /vendor/laravel/framework/src/Illuminate/Routing/Route.php

并在调试期间查看堆栈调用时设置断点。

顺便说一句,我读过,可以使用此功能在您的X-CSRF token来电标头中设置ajax

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

上述内容摘自http://words.weareloring.com/development/laravel/laravel-4-csrf-tokens-when-using-jquerys-ajax/

我想知道Taylor Otwell是否有关于架构设计和框架解释的一些信息。 我打算读一下Symfony,但不确定是否能帮助我更彻底地理解Laravel的基础。 我知道Laravel API文档很有用,但更像是对设计的研究。有什么想法吗?