Как указать браузеру что бы он слал данные через XHR в кодировке страницы я так и не понял.
AJAX всегда в UTF-8.
Аактуально для версии 18.0.0.
Нашел только один способ побороть проблему: переконвертировать данные суперглобалдьных переменных до инициализации ядра.Важно сделать именно до подключения ядра, поскольку если сделать это позже, то системный объект D7 $request (Bitrix\Main\HttpRequest) будет инициализирован с UTF-8 данными. А так как мы не можем всегда напред знать какие компоненты мы захотим вызвать через ajax и будет ли использован системный объект $request, то лучше его перекодировать.
Ниже код обработчика.
Код |
---|
<?php
namespace Devtop\Site\Sunways\Ajax\Component;
use OBX\Core\Components\Ajax;
use Bitrix\Main\Text\Encoding;
ob_start();
define('PUBLIC_AJAX_MODE', true);
define('STOP_STATISTICS', true);
define('NO_AGENT_CHECK', true);
define("NOT_CHECK_PERMISSIONS", true);
/**
* @global \CMain $APPLICATION
* @global \CUser $USER
*/
// Подключаем классы конвертации до инициализации ядра (а значит и $request-объекта)
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/lib/type/dictionary.php');
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/lib/errorcollection.php');
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/lib/text/encoding.php');
// конвертируем данные пришедшие по xhr из UTF-8 в cp1251
$_POST = Encoding::convertEncoding($_POST, 'UTF-8', 'windows-1251');
$_GET = Encoding::convertEncoding($_GET, 'UTF-8', 'windows-1251');
$_REQUEST = Encoding::convertEncoding($_REQUEST, 'UTF-8', 'windows-1251');
$_COOKIE = Encoding::convertEncoding($_COOKIE, 'UTF-8', 'windows-1251');
// Теперь подключаем ядро. Теперь при инициализации $request-объекта кодировка будет в порядке
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');
//$request = \Bitrix\Main\Application::getInstance()->getContext()->getRequest();//dbg
// Все что ниже для проблемы не принципиально,
// но показываеть важность почему надо перекодировать заранее
// Ибо программист может в любом result_modifier-е
// сохранить параметры вызова в кеш и вызвать ЛЮБОЙ компонент через ajax.
$ajaxComponent = Ajax::getByCallId($_REQUEST[Ajax::MARKER_CALL_ID]);
if( $ajaxComponent instanceof Ajax ) {
$parentComponent = false;
if( !empty($ajaxComponent->additionalData['ParentBitrixComponent']) ) {
$parentComponent = new \CBitrixComponent();
$parentComponent->InitComponent(
$ajaxComponent->additionalData['ParentBitrixComponent']['name'],
$ajaxComponent->additionalData['ParentBitrixComponent']['template']
);
$parentComponent->initComponentTemplate();
}
$APPLICATION->IncludeComponent(
$ajaxComponent->name,
$ajaxComponent->template,
$ajaxComponent->params,
$parentComponent,
['HIDE_ICONS' => 'Y']
);
}
else {
ShowError('Данные ajax-вызова компонента не найдены');
}
|