提问人:Jaimitove 提问时间:11/7/2023 最后编辑:Jaimitove 更新时间:11/16/2023 访问量:67
PHP Yii2 REST POST / 缺少必需参数
PHP Yii2 REST POST / Missing required parameters
问:
非常感谢您的帮助。
我正在使用Yii2。我想使用 REST POST 请求向服务器发送单词列表,服务器将翻译单词并发回它们的翻译。
当我发送 POST 请求时,我在浏览器 JavaScript 控制台中收到以下消息: 名称“错误请求” 消息“缺少必需的参数:单词” 代码 0 状态 400 类型 “yii\web\BadRequestHttpException”
我正在使用这个命令运行 PHP:php yii serve。
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());
}
}
配置/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 (cli) (内置: Aug 18 2023 11:41:11) (NTS) Zend Engine v4.1.2 版本 使用 Zend OPcache v8.1.2-1ubuntu2.14 使用 Xdebug v3.2.1 Yii2 (2.0.48.1版本)
非常感谢您的帮助。
我在谷歌上搜索解决方案,但我什么也没找到。
答:
回答这个问题..
“错误请求 (#400):缺少必需的参数:单词”
是的,正如我在您的 js 中看到的那样,您正在发送,因此可能是您的 Yii2 如何处理请求。words
当我检查您的控制器时,需要您的参数,但在您的 POST 请求中,参数通常在正文中发送,而不是在 url 中发送。RestTranslationController
actionTranslate($words)
words
这就是我如何得出这导致您错误的。 你能把它修改成这个吗?
public function actionTranslate()
{
$words = Yii::$app->request->post('words');
return Translation::translate($words);
}
我们在这里用于确保您的控制器将获取参数(单词),并希望它不会导致您出现错误请求错误。Yii::$app->request->post('words')
编辑
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
评论
今天我正在阅读 Yii 文档,特别是我正在阅读句柄请求部分,我遇到了 Yii 如何处理 POST 请求。
以下是文档的摘录:
在实现 RESTful API 时,您经常需要检索通过 PUT、PATCH 或其他请求方法提交的参数。你可以通过调用 yii\web\Request::getBodyParam() 方法来获取这些参数。例如
$request = Yii::$app->request;
返回所有参数
$params = $request->bodyParams;
返回参数“id”
$param = $request->getBodyParam('id');
信息:与 GET 参数不同,通过 POST、PUT、PATCH 等提交的参数在请求正文中发送。当您通过上述方法访问这些参数时,请求组件将解析这些参数。你可以通过配置 yii\web\Request::$parsers 属性来自定义这些参数的解析方式。
--摘录结束
我们还需要在config/web.php文件中添加以下内容:
...
'components' => [
'request' => [
'cookieValidationKey' => 'Your key',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
]
],
...
上一个:PHP Yii2 扩展开发
下一个:Yii2 使用多个数据库进行迁移
评论
console.log(words)
{ words: words }
post
console.log(words)
Array(3) [ "dog", "cat", "bear" ]
{words: words}