Вопрос

I checked this and built a Controller that executes an ajax request sent on adminhtml through a button, but I get an error 404 on my console.

POST http://myurl/system_config/customAjax/key/ade007809d7e313c38d42de6c2fa64ad8/?isAjax=true 404 (Forbidden)

I don't think you should pay much attention to the word "Forbidden" as this is an open issue on their repo and I guess it will be corrected. The important thing here is the error 404, and why doesn't it call my controller. Any ideas?

etc\adminhtml\system.xml:

<field id="vendor_actionbutton" type="button" sortOrder="26" showInDefault="1" showInWebsite="1" showInStore="0">
    <frontend_model>Vendor\Module\Block\Adminhtml\System\Config\Mybutton</frontend_model>
</field>

Block\Adminhtml\System\Config\Mybutton.php:

<?php
namespace Vendor\Module\Block\Adminhtml\System\Config;

use Magento\Backend\Block\Template\Context;
use Magento\Config\Block\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;

class Mybutton extends Field
{
    /**
     * @var string
     */
    protected $_template = 'Vendor_Module::system/config/customajax.phtml';

    /**
     * @param Context $context
     * @param array $data
     */
    public function __construct(
        Context $context,
        array $data = []
    ) {
        parent::__construct($context, $data);
    }

    /**
     * Remove scope label
     *
     * @param  AbstractElement $element
     * @return string
     */
    public function render(AbstractElement $element)
    {
        $element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue();
        return parent::render($element);
    }

    /**
     * Return element html
     *
     * @param  AbstractElement $element
     * @return string
     */
    protected function _getElementHtml(AbstractElement $element)
    {
        return $this->_toHtml();
    }

    /**
     * Return ajax url for send button
     *
     * @return string
     */
    public function getAjaxUrl()
    {
        return $this->getUrl('vendor_module/system_config/customAjax');
    }

    /**
     * Generate send button html
     *
     * @return string
     */
    public function getButtonHtml()
    {
        $button = $this->getLayout()->createBlock(
            'Magento\Backend\Block\Widget\Button'
        )->setData(
            [
                'id' => 'send_button',
                'label' => __('Send'),
            ]
        );

        return $button->toHtml();
    }
}

Controller\Adminhtml\System\Adminhtml\System\Config\CustomAjax.php:

<?php
namespace Vendor\Module\Controller\Adminhtml\System\Config;

class CustomAjax extends \Magento\Backend\App\Action
{
    /**
     * @var \Magento\Framework\Controller\Result\JsonFactory
     */
    protected $resultJsonFactory;

    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory

    )
    {
        parent::__construct($context);
        $this->resultJsonFactory= $resultJsonFactory;
    }

    public function execute()
    {
        $params = $this->getRequest()->getParams();
        $resultJson = $this->resultJsonFactory->create();

        return $resultJson->setData([
            'messages' => 'Successfully. Params: ' . json_encode($params),
            'error' => false
        ]);
    }
}

view\adminhtml\templates\system\config\customajax.phtml:

<script>
    require([
        'jquery',
        'prototype'
    ], function(jQuery){

        var sendSpan = jQuery('#send_span');

        jQuery('#send_button').click(function () {
            var params = {};
            new Ajax.Request('<?php echo $block->getAjaxUrl() ?>', {
                parameters:     params,
                loaderArea:     false,
                asynchronous:   true
        });

    });
</script>

<?php echo $block->getButtonHtml() ?>
<span class="send-indicator" id="send_span">
    <img class="processing" hidden="hidden" alt="Sending" style="margin:0 5px" src="<?php echo $block->getViewFileUrl('images/process_spinner.gif') ?>"/>
    <img class="sent" hidden="hidden" alt="Sended" style="margin:-3px 5px" src="<?php echo $block->getViewFileUrl('images/rule_component_apply.gif') ?>"/>
    <span id="send_message_span"></span>
</span>

etc\adminhtml\routes.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="admin">
        <route id="module" frontName="module">
            <module name="Vendor_Module" before="Magento_Backend" />
        </route>
    </router>
</config>

Is it maybe this vendor_module/system_config/customAjax wrong? Should I write it differently? (I have seen another module working with this expression though)

Это было полезно?

Решение

I think you are missing your routes.xml file in app/code/Vendor/Module/etc/adminhtml/routes.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="admin">
        <route id="vendor_module" frontName="vendor_module">
            <module name="Vendor_Module" />
        </route>
    </router>
</config>

Другие советы

I experienced the same issue - receiving a 404 error on a custom ajax controller.

My ajax controller URL is retrieved using

$urlBuilder->getUrl('<frontname>/<action>');

and my controller file was at location

<module files>/Controller/Adminhtml/<Action.php>

After hours of debugging I found that the full path that Magento 2 creates for admin ajax requests is

<vendor>\<module>\controller\adminhtml\<action>\index

I then moved my controller file to be under:

<module files>/Controller/Adminthtml/<Action>/Index.php

The error was resolved - hope this helps someone else!

I don't know how it is possible, but i had the same error and i fixed it adding to controller

/**
 * Array of actions which can be processed without secret key validation
 *
 * @var string[]
 */
protected $_publicActions = ['test'];

and it starts to work, but now it continues to work even if $_publicActions is removed or commented out.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с magento.stackexchange
scroll top