Javascript Yii2 302重定向jQuery AJAX请求,重定向整个页面
我有一个行动:Javascript Yii2 302重定向jQuery AJAX请求,重定向整个页面,javascript,php,jquery,ajax,yii2,Javascript,Php,Jquery,Ajax,Yii2,我有一个行动: public function actionAjaxLoadBasketSmall() { $this->enableCsrfValidation = false; return $this->renderPartial('@app/views/basket/_small'); } 一些JavaScript function loadBasketSmall() { $.ajax({ method: "POST",
public function actionAjaxLoadBasketSmall() {
$this->enableCsrfValidation = false;
return $this->renderPartial('@app/views/basket/_small');
}
一些JavaScript
function loadBasketSmall() {
$.ajax({
method: "POST",
url: "/basket/ajax-load-basket-small",
dataType: "html",
beforeSend: function () {
$('#basketSmall').addClass('loading');
},
complete: function (data) {
$("#basketSmall").replaceWith(data.responseText);
}
});
}
从该函数调用,例如:
function handleProductTileButton(e) {
e.preventDefault();
var input = $(this);
$('#basketSmall').addClass('loading');
$.ajax({
method: "GET",
url: "/basket/ajax-add-product",
dataType: "html",
data: {
productId: input.data('product-id'),
quantity: 1,
},
beforeSend: function () {
input.addClass('loading');
},
complete: function (data) {
$('.top-bar .search-results').html(data.responseText);
input.removeClass('loading');
loadBasketSmall();
}
});
}
每当Ajax调用完成时,整个页面都会被重定向到/basket/Ajax load basket small
这些是响应头。注意302响应代码。
因此,让服务器发送重定向响应的是语言检测 为了解决这个问题,我将这段代码添加到我的基本控制器类中
public function init() {
parent::init();
$this->initJsLang();
}
public static function jsDefineLang() {
return "const LANG = '" . \Yii::$app->language ."';";
}
protected function initJsLang() {
$this->getView()->registerJs(static::jsDefineLang(), \yii\web\View::POS_HEAD);
}
并相应地更新了我的JavaScript:
function handleProductTileButton(e) {
e.preventDefault();
var input = $(this);
$('#basketSmall').addClass('loading');
$.ajax({
method: "GET",
url: "/" + LANG + "/basket/ajax-add-product",
dataType: "html",
data: {
productId: input.data('product-id'),
quantity: 1,
},
beforeSend: function () {
input.addClass('loading');
},
complete: function (data) {
$('.top-bar .search-results').html(data.responseText);
input.removeClass('loading');
loadBasketSmall();
}
});
}
function loadBasketSmall() {
$.ajax({
method: "GET",
url: "/" + LANG + "/basket/ajax-load-basket-small",
dataType: "html",
beforeSend: function () {
$('#basketSmall').addClass('loading');
},
complete: function (data) {
$("#basketSmall").replaceWith(data.responseText);
}
});
}
在穆罕默德的建议下,最终的解决方案是什么 LanguageAsset.php
<?php
namespace frontend\assets;
use yii\web\AssetBundle;
/**
* Language application asset bundle.
*/
class LanguageAsset extends AssetBundle
{
public function init() {
parent::init();
$view = \Yii::$app->controller->view;
$language = \Yii::$app->language;
$js = "const LANG='{$language}';";
$view->registerJs($js, $view::POS_HEAD);
}
}
响应AJAX请求的重定向不能“重定向整个页面”。该重定向是对后台请求的响应,因此它也将在后台处理。只有AJAX请求本身会受到这种重定向的影响。如果你看到“整个页面”改变了位置,那一定是其他原因。只有在请求发出后调用JavaScript函数时才会发生这种情况。不知道你在说什么。告诉我们你在何时何地打电话,很简单。我所需要做的就是在控制台中调用
loadBasketSmall()
,让它发生。那么,您所需要做的就是停止这样做。哇,那很容易。(如果这不是您希望得到的响应-那么已经给我们一个正确的问题描述了…)为什么控制器中有所有这些函数可以在视图中定义LANG
,为什么两个函数只是初始化控制器中的const
?除此之外,如果您仍然需要这样做,您应该将其添加到beforeAction
中,而不是init中,因为您需要仅在该控制器中加载视图时才定义const,因此它在我的所有前端页面上全局注册。我以前可以这样做,但在我看来它同样好。分开函数的原因是,如果需要在控制器中,我可以重写定义LANG const的函数。这不一样,否则beforeAction
不应该在那里。如果查看请求的生命周期,则在创建操作之前调用init
,在创建操作之后但在运行操作之前调用beforeAction
。如果选择1)一个assetBundle
类并将变量注入文档的头部,则仍然可以将前端代码和服务器端代码分开。2) 或者简单地将其添加到
标记内的布局文件中。我找不到合理的理由将const
初始化隐藏在控制器中,除了您之外,没有人知道它在哪里。如果你离开工作,把项目交给别人,任何其他的开发人员都会不停地吹毛求疵。我有几个布局文件。我不希望它们中的每一个都有相同的代码。before函数也将完成这项工作。我想它可能会更整洁。而且它不是隐藏的。它位于一个抽象类中,所有前端控制器都从该抽象类扩展而来。资产绑定用于注册文件。我不会让一个单独的PHP脚本呈现一个js文件,然后通过一个资产包包含它。
use frontend\assets\LanguageAsset;
LanguageAsset::register($this);