【问题标题】:Laravel Ajax Call to ControllerLaravel Ajax 调用控制器
【发布时间】:2018-04-19 06:09:12
【问题描述】:

我对@9​​87654321@ 很陌生,我在访问Controller 中的特定方法时遇到问题。我正在尝试根据下拉菜单更改数据库值(语言)。

settings.profile.blade

<select id="accountLanguage" class="form-control" method="GET">
    <option value="en" {{ ($strLanguage == 'en') ? 'selected = "selected"' : "" }} >English</option>
    <option value="es" {{ ($strLanguage == 'es') ? 'selected = "selected"' : "" }} >Español</option>
    <option value="he" {{ ($strLanguage == 'fr') ? 'selected = "selected"' : "" }} >French</option>
</select>

配置文件控制器

public function index() {

    $objUser = Auth::User();

    $strLanguage = $objUser->lang;

    return view("application.settings.profile",[
        'objUser' => $objUser,
        'strLanguage' => $strLanguage
    ]); 

}   

// THE METHOD I NEED ACCESS TO
function update( $strLang ) { 

    $objUser = Auth::User();

    // UPDATE LANGUAGE
    $bolUpdated = $objUser->updateLanguage( $strLang );

    // RETURN
    return response()->json( $bolUpdated );
 }

路线

Route::namespace( 'Settings' )->prefix( 'settings' )->group( function () {

    ...

    // PROFILE
    Route::resource( 'profile', 'ProfileController', ['only' => ['index','update']] );
    Route::get('test', 'ProfileController@update');
});

settings.profile.js

function initProfileManager() {

    // GET ELEMENTS
    var domUpdateLanguage = $('#accountLanguage');

    var updateLanguage = function() {

        // MAKE AJAX CALL
        $.ajaxq( {
            // url:'/settings/profile',
            url:'./test',
            method:'GET',
            success: function( bolUpdated ) { 
                if( bolUpdated ) { 
                    alert('OK');
                }   
            },  
            fail: function() {
                alert('NO');
            }   
         }); 
         location.reload();
    };  
    domUpdateLanguage.on( 'change', updateLanguage );

目前的情况,我收到此错误Too few arguments to function App\Http\Controllers\Settings\ProfileController::update(), 0 passed and exactly 1 expected。我理解错误,但不确定如何传递参数。

如果我从JS 中取消注释url 行,我永远不会进入update 方法,我最终只会运行index 两次。

任何帮助将不胜感激。

编辑 1

奇怪。我尝试定义一个随机值,但它仍然会给我这个错误。我认为您可能是对的,这是语法问题。不明白为什么会发生。

function initProfileManage(strLang) {

    // GET ELEMENTS
    var domUpdateLanguage           = $('#accountLanguage');

    var updateLanguage = function() {

        // MAKE AJAX CALL
        $.ajaxq({
            // url:'/settings/profile',
            url:'./test',
            method:'POST',
            data: { 
                    strLang: newLang,
            }   
            success: function( bolUpdated ) { 
                if( bolUpdated ) { 
                    alert('OK');
                }   
            },  
            fail: function() {
                alert('NO');
            }   
         }); 
         location.reload();
    };  

    // UPATE LANGUAGE EVENT
    domUpdateLanguage.on( 'change', updateLanguage );
}

【问题讨论】:

    标签: javascript php ajax laravel controller


    【解决方案1】:

    这是对您问题的完整答案

    使用 POST 请求而不是 GET

    因为您正在更新用户的语言,所以使用 POST 请求更安全

    // MAKE AJAX CALL
    $.ajax( {
        // url:'/settings/profile',
        url:'./test',
        method:'POST',
        data: {
           strLang: newLang
        },
        success: function( bolUpdated ) { 
            if( bolUpdated ) { 
                alert('OK');
            }   
        },  
        fail: function() {
            alert('NO');
        }   
    }); 
    

    并且不要忘记通过 data 属性在您的 post 请求中传递 strLang。

    防止 CSRF 攻击

    将 csrf 令牌存储在 HTML 元标记中:

    <meta name="csrf-token" content="{{ csrf_token() }}">
    

    自动将令牌添加到所有请求头中:

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

    创建一个路由来处理您的 ajax 请求:

    Route::post('test', 'ProfileController@update');
    

    通过控制器中的 $request 对象获取 strLang:

    function update( $request ) { 
    
        $objUser = Auth::User();
    
        // UPDATE LANGUAGE
        $bolUpdated = $objUser->updateLanguage( $request->strLang );
    
        // RETURN
        return response()->json( $bolUpdated );
    }
    

    如果您使用的是 HTML5,您的 settings.profile.blade 应该如下所示:

    <select id="accountLanguage" class="form-control" method="GET">
        <option value="en" {{ ($strLanguage == 'en') ? 'selected' : '' }} >English</option>
        <option value="es" {{ ($strLanguage == 'es') ? 'selected' : '' }} >Español</option>
        <option value="he" {{ ($strLanguage == 'fr') ? 'selected' : '' }} >French</option>
    </select>
    

    在你的 index 方法中,$objUser 已经包含了 lang 属性

    public function index() {
    
        $objUser = Auth::User();
    
        return view("application.settings.profile",[
            'objUser' => $objUser
        ]); 
    
    }  
    

    从选择元素中获取新的语言:

    $('#accountLanguage').change(function () {
         initProfileManager(this.value);
    });
    

    【讨论】:

    • 感谢您的详细解决方案。我更改了您的建议,似乎我在js 文件上遇到了错误。 Uncaught SyntaxError: Unexpected identifier 用于 strLang: newLang 部分。我认为这可能与您所说的有关通过 data 属性在 post 请求中传递 strLang 的内容有关?
    • 是的,您必须从 axample 的输入中获取新的 Lang。例如:var newLang = $('#inputId').val(); 然后将其传递给数据对象
    • 我是否从blade 传递它?
    • 这里更新的是用户语言,所以当用户选择其他语言时,您应该调用initProfileManager,并在参数中使用所选语言:例如initProfileManager(this.value);
    • 在您的 AJAX 方法中检查数据属性末尾是否缺少逗号
    【解决方案2】:

    将您的路线更改为:

    Route::post('test', 'ProfileController@update');
    

    还有你的 ajax 对象:

    method:'POST',
    

    您也必须以某种方式实际传递 $strLang(因为 update() 方法期望这样做,如错误消息所述)。

    哦,你真的不需要你选择的 HTML 中的方法属性;)

    【讨论】:

    • 为什么发布?它导致csrf 不包括问题。太复杂了。
    • 因为 Laravel 很容易通过一个初始的 ajaxSetup() 来解决这些问题。对于方法:如果您遵循“标准”,您最终会得到:UPDATE 始终为 POST 或 PUT。
    【解决方案3】:

    你应该在路由中定义语言

    Route::get('test/{strLang}', 'ProfileController@update');` 
    

    以及将其作为变量传递给js代码中的url:'/test/' + strLang

    【讨论】:

      猜你喜欢
      • 2017-06-06
      • 2014-10-07
      • 2018-03-28
      • 2014-11-18
      • 1970-01-01
      • 2016-10-16
      • 1970-01-01
      • 2018-01-24
      • 2014-05-16
      相关资源
      最近更新 更多