非常感谢你的帮助.

我用的是艺二号.我想使用REST POST请求将单词列表发送到服务器,服务器将翻译这些单词并将它们的翻译发回.

当我发送POST请求时,我在浏览器脚本控制台中收到以下消息: 名称"Bad Request" 消息"缺少必需的参数:字词" 代码0 状态400 键入"yii\web\BadRequestHttpException"

我正在使用以下命令运行PHP:php yii服务器.

JavaScript

window.onload = (event) => {
    document.querySelector("#translate").addEventListener("click", translate)
}

function translate() {
    const textarea = document.getElementById("words");
    const words = textarea.value.replace(/\r\n/g, "\n").split("\n");
    post('http://localhost:8080/index.php/rest-translation/translate', words)
}

async function post(url, words) {
    console.log(words)

    let options = {
        method: "POST",
        body: JSON.stringify({words: words})
    }

    const response = await fetch(url, options)
    if (response.ok) {
        response.json()
    }
}

这是一个视图:

<?php

use yii\helpers\Html;
use yii\widgets\DetailView;
use yii\widgets\ActiveForm;
use app\assets\TranslationAsset;

/** @var yii\web\View $this */
/** @var app\models\Book $book */
/** @var app\models\BookSection $section */

$this->title = $section->title;
$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Section'), 'url' => ['book']];
$this->params['breadcrumbs'][] = $this->title;
\yii\web\YiiAsset::register($this);
?>
<div class="translate-section">

    <h1><?= Html::encode($this->title) ?></h1>

    <?= DetailView::widget([
        'model' => $book,
        'attributes' => [
            'id',
            'name',
        ],
    ]) ?>
    <?= DetailView::widget([
        'model' => $section,
        'attributes' => [
            'title',
        ],
    ]) ?>
    <div>
        <?php $form = ActiveForm::begin(); ?>
        <table>
            <tr>
                <td><textarea id="words"></textarea></td>
                <td><textarea id="first-translation"></textarea></td>
                <td><textarea id="second-translation"></textarea></td>
            </tr>
        </table>
        <button id="translate" type="button">Translate</button>

        <div class="form-group">
            <?= Html::submitButton(Yii::t('app', 'Save'), ['class' => 'btn btn-success']) ?>
        </div>

        <?php ActiveForm::end(); ?>

    </div>
    <?php TranslationAsset::register($this) ?>
</div>

这是REST控制器:

<?php

namespace app\controllers;

use app\models\Translation;
use yii\rest\ActiveController;

class RestTranslationController extends ActiveController
{
    public $modelClass = 'app\models\Translation';

    public function actionTranslate($words)
    {
        return  Translation::translate($words);
    }

    public function behaviors()
    {
        $behaviors = parent::behaviors();

        // remove authentication filter
        $auth = $behaviors['authenticator'];
        unset($behaviors['authenticator']);

        // add CORS filter
        $behaviors['corsFilter'] = [
            'class' => \yii\filters\Cors::class,
        ];

        // re-add authentication filter
        $behaviors['authenticator'] = $auth;
        // avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
        $behaviors['authenticator']['except'] = ['options'];

        return $behaviors;
    }
}

这就是模型:

<?php

namespace app\models;

use Yii;

/**
 * This is the model class for table "translation".
 *
 * @property int $id
 * @property int $sourceEntryId
 * @property string $languageId
 * @property string $typeId
 * @property int $translationEntryId
 */
class Translation extends \yii\db\ActiveRecord
{
    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return 'translation';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['sourceEntryId', 'languageId', 'typeId', 'translationEntryId'], 'required'],
            [['sourceEntryId', 'translationEntryId'], 'integer'],
            [['languageId', 'typeId'], 'string', 'max' => 10],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id' => Yii::t('app', 'ID'),
            'sourceEntryId' => Yii::t('app', 'Source Entry ID'),
            'languageId' => Yii::t('app', 'Language ID'),
            'typeId' => Yii::t('app', 'Type ID'),
            'translationEntryId' => Yii::t('app', 'Translation Entry ID'),
        ];
    }

    public static function translate($words)
    {
        //<TO DO>:Find and return the translation.
    }

    /**
     * {@inheritdoc}
     * @return TranslationQuery the active query used by this AR class.
     */
    public static function find()
    {
        return new TranslationQuery(get_called_class());
    }
}

config/web.php

<?php

$params = require __DIR__ . '/params.php';
$db = require __DIR__ . '/db.php';

$config = [
    'id' => 'basic',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log'],
    'aliases' => [
        '@bower' => '@vendor/bower-asset',
        '@npm'   => '@vendor/npm-asset',
    ],
    'components' => [
        'request' => [
            // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
            'cookieValidationKey' => 'xxxxxxxx',
            'parsers' => [
                'application/json' => 'yii\web\JsonParser',
            ]
        ],
        /*'response' => [
            'format' => yii\web\Response::FORMAT_JSON,
            'charset' => 'UTF-8',
            // ...
        ],*/
        'cache' => [
            'class' => 'yii\caching\FileCache',
        ],
        'user' => [
            'identityClass' => 'app\models\User',
            'enableAutoLogin' => true,
        ],
        'errorHandler' => [
            'errorAction' => 'site/error',
        ],
        'mailer' => [
            'class' => \yii\symfonymailer\Mailer::class,
            'viewPath' => '@app/mail',
            // send all mails to a file by default.
            'useFileTransport' => true,
        ],
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
        'db' => $db,
        
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => true,
            'enableStrictParsing' => false
        ]
    ],
    'params' => $params,
];

if (YII_ENV_DEV) {
    // configuration adjustments for 'dev' environment
    $config['bootstrap'][] = 'debug';
    $config['modules']['debug'] = [
        'class' => 'yii\debug\Module',
        // uncomment the following to add your IP if you are not connecting from localhost.
        //'allowedIPs' => ['127.0.0.1', '::1'],
    ];

    $config['bootstrap'][] = 'gii';
    $config['modules']['gii'] = [
        'class' => 'yii\gii\Module',
        // uncomment the following to add your IP if you are not connecting from localhost.
        //'allowedIPs' => ['127.0.0.1', '::1'],
    ];
}

return $config;

我的环境: PHP 8.1.2-1ubuntu2.14 Zend Engine v4.1.2 使用Zend OPcache v8.1.2-1ubuntu2.14 使用Xdebug v3.2.1 Yii2(2.0.48.1)

非常感谢你的帮助.

我在谷歌上搜索了一下解决方案,但什么也没找到.

推荐答案

回答这个问题...

"错误请求(#400):缺少必需的参数:Words"

是的,正如我在您的js中看到的,您发送的是words,所以它处理请求的方式可能会影响到您的aii2.

当我判断您的控制器RestTranslationController时,actionTranslate($words)期望您的words参数,但在您的POST请求中,参数通常是在body中发送的,而不是在url中.

这就是我得出的结论,这导致了您的错误. 你能把它改成这个吗?

public function actionTranslate()
{
   $words = Yii::$app->request->post('words');
   return Translation::translate($words);
}

我们在这里使用Yii::$app->request->post('words')来确保您的控制器将获得参数(words),并希望它不会导致您的错误请求错误.

Edit

public function actionTranslate()
{
  $request_raw = file_get_contents('php://input');
  $request = json_decode($request_raw, true);
  $words = $request['words'];
  return Translation::translate($words);
}

使用php://input从请求正文中读取原始数据.

Javascript相关问答推荐

如何在pixi js中画一条简单的线

ChartJS:分组堆叠条形图渲染错误

如何计算数组子级的深度- Vue.js

输入有关HTML复选框的已判断属性的信息

无法在page. evalve()内部使用外部函数

设置默认值后动态更新japbox或调色板

在NextJS中使用计时器循环逐个打开手风琴项目?

如何从对象嵌套数组的第二级对象中过滤出键

foreach循环中的Typescript字符串索引

如何避免移动设备中出现虚假调整大小事件?

过滤对象数组并动态将属性放入新数组

react/redux中的formData在expressjs中返回未定义的req.params.id

InDesign—创建一个独立的窗口,在文档中进行更正时保持打开状态

如何在不创建新键的情况下动态更改 map 中的项目?

在网页上添加谷歌亵渎词

在拖放时阻止文件打开

如何从隐藏/显示中删除其中一个点击?

在使用HighChats时如何避免Datatables重新初始化错误?

禁用.js文件扩展名并从目录导入隐式根index.js时,找不到NodeJS导入模块

在Odoo中如何以编程方式在POS中添加产品