Laravel 验证:必须是带有“json”规则的有效 JSON 字符串

Posted

技术标签:

【中文标题】Laravel 验证:必须是带有“json”规则的有效 JSON 字符串【英文标题】:Laravel validation: Must be a valid JSON string with the "json" rule 【发布时间】:2021-02-27 19:10:45 【问题描述】:

我正在制作 Laravel API,但我似乎无法在其中一篇文章中发送 JSON 数据。我检查了***中的其他帖子,但似乎我的JSON请求是正确的,所以我似乎找不到错误:

这是我的控制器方法中的代码:

$validator = Validator::make($request->all(), [
    "name" => "required|string",
    "colors" => "json",
     "sizes" => "json"
]);

if($validator->fails())
    return response()->json(["errors" => $validator->errors()], 400);

这是请求正文:


 "name": "Test",
 "colors": 
   "Man": "#0000ff",
   "Second": "#FF0000"
 ,
 "sizes": 
   "titles": "20px"
 

错误:


   "errors": 
       "colors": ["The colors must be a valid JSON string."],
       "text_sizes": ["The text sizes must be a valid JSON string."]
   

似乎是什么问题?谢谢!

【问题讨论】:

你传递的是一个 json 对象,而不是一个 json 字符串。所以为了这个工作我认为你需要做JSON.parse()。这样你就会得到类似"\"colors\": \n \"Man\": \"#0000ff\",\n \"Second\": \"#FF0000\"\n " 我试过这样做:"colors": "'Main': '#0000ff','Secondary': '#FF0000'" 但没有成功。这不是一个有效的 json 字符串吗? 不,我认为您需要使用反斜杠:"\"colors\": \"Man\": \"#0000ff\",\"Second\": \"#FF0000\" ”。 PS我的意思是JSON.stringify()当然。 我明白了。那么,如何在验证 JSON 字段之前对其进行字符串化?因为我只希望在我的情况下,两个属性是 JSON 数据。 @Tom 请在帖子中回复,以便我可以将我的帖子标记为已回答。谢谢。 【参考方案1】:

你需要传递一个 JSON 字符串而不是 JSON 对象。这可以通过json_encodeJSON.stringify 完成。

作为对您上一条评论的回答。:

您可以在前端应用程序中使用JSON.stringify 执行此操作,也可以使用prepareForValidation() 实现表单请求:https://laravel.com/docs/8.x/validation#prepare-input-for-validation。

您将在哪里对 json 属性执行 json_encode()。喜欢:

protected function prepareForValidation()

    $this->merge([
        'colors' => json_encode($this->colors),
        'text_sizes' => json_encode($this->text_sizes)
    ]);

或者在你的情况下:

$validator = Validator::make($request->merge([
        'colors' => json_encode($request->colors),
        'text_sizes' => json_encode($request->text_sizes)
    ]), [
    "name" => "required|string",
    "colors" => "json",
     "sizes" => "json"
]);

【讨论】:

【参考方案2】:

laravel 有一个方便的方法来验证请求请按照这些步骤为 api 发出你自己的请求和响应 1-php artisan make:request YourRequest

然后像这样自定义您的请求

  <?php
    
    namespace App\Http\Requests;
    
    use Illuminate\Contracts\Validation\Validator;
    use Illuminate\Foundation\Http\FormRequest;
    use Illuminate\Http\Exceptions\HttpResponseException;
    use Illuminate\Http\Response;
    
    class OrderRequest extends FormRequest
    
    
        /**
         * Determine if the user is authorized to make this request.
         *
         * @return bool
         */
        public function authorize(): bool
        
            return true;
        
    
        /**
         * Get the validation rules that apply to the request.
         *
         * @return array
         */
        public function rules(): array
        
    
            $rules = [
                'your filed name' => 'required',
                
            ];
            return $rules;
        
    
        /**
         * Get the error messages that apply to the request parameters.
         *
         * @return array
         */
        public function messages()
        
            return [
                'your field name' => 'custom message',
              
            ];
        
    
        /**
         * Handle a failed validation attempt.
         *
         * @param Validator $validator
         * @return void
         *
         * @throws ValidationException
         */
        protected function failedValidation(Validator $validator)
        
            $error = collect($validator->errors())->collapse()->toArray();
            $errors = implode(' | ', $error);
            throw new HttpResponseException(response()->json(
                ['response' => ['status' => false, 'message' => $errors]],
                Response::HTTP_UNPROCESSABLE_ENTITY));
        
    

这将按照 laravel 的推荐及其专业的方式解决错误

然后在控制器中使用这个请求。

如果你想使用自己的代码,那么

只需使用json_encode($this-&gt;text_sizes)

【讨论】:

谢谢,但是当我只想立即验证两个字段时,这似乎不切实际。我现在没有任何复杂的逻辑,所以我没有必要做这一切。【参考方案3】:

我找到了一个简单的解决方案,就是用双引号来表示一个json字符串,并把json里面的双引号转义:

"name": "Test", "colors": "\"Man\": \"#0000ff\",\"Second\": \"#FF0000\"", "sizes": "\"titles\": \"20px\""

这解决了我从 Insomnia Api rest 发送 json 字符串的问题。

【讨论】:

以上是关于Laravel 验证:必须是带有“json”规则的有效 JSON 字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何在 laravel 8 中添加带有 where 条件的验证规则?

Laravel 图像验证

如何在 laravel 8 中为 API 返回验证规则和消息作为 JSON

Laravel 验证:存在附加列条件 - 自定义验证规则

Laravel 自定义验证规则

Laravel Mime 类型验证(KML 文件)