Laravel 8 Jetstream Inertia 所有 Inertia 请求都必须收到有效的 Inertia 响应

Posted

技术标签:

【中文标题】Laravel 8 Jetstream Inertia 所有 Inertia 请求都必须收到有效的 Inertia 响应【英文标题】:Laravel 8 Jetstream Inertia All Inertia requests must receive a valid Inertia response 【发布时间】:2021-09-20 10:39:17 【问题描述】:

我一直在尝试为我的问题找到正确的答案我知道这个问题在here 之前以及实际上在许多其他地方已经提出过,但是我没有找到适合我的问题的答案。

vue 组件

FooterNewsletter.vue

<template>
    <div class="lg:w-2/4 md:w-1/2 w-full px-8 border-l-2">
        <p class="font-bold text-3xl">
            Don't want to miss the latest cryptocurrency news?
        </p>
        <p class="py-3 text-lg">
            Get the latest news and updates by subscribing to our free
            newsletter ????
        </p>
        <form @submit.prevent="subscribeToNewsletter">
            <div class="flex flex-col">
                <div class="flex">
                    <input
                        v-model="form.email"
                        type="text"
                        name="post_title"
                        class="
                            border-primary
                            focus:border-primary
                            focus:ring-offset-transparent
                            focus:ring-transparent
                        "
                        id="exampleFormControlInput1"
                        placeholder="Your E-mail"
                    />
                    <input
                        type="submit"
                        value="Subscribe"
                        :disabled="form.processing"
                        class="px-5 py-2 bg-primary text-white cursor-pointer"
                    />
                </div>
            </div>
        </form>
    </div>
</template>

<script>

export default 
    props: [],
    components: 

    ,
    data() 
        return 
            form: this.$inertia.form(
                email: "",
            ),
        ;
    ,
    methods: 
        subscribeToNewsletter() 
            this.form
                .transform((data) => (
                    ...data,
                    // remember: this.form.remember ? "on" : "",
                ))
                .post(this.route("newsletter.store"), 
                    onSuccess: (data) => 
                        console.log("data", data);
                    ,
                    onError: (data) => 
                        console.log("data", data);
                    ,
                );
        ,
    ,
;
</script>

控制器

NewsletterController.php

namespace App\Http\Controllers;

use App\Http\Requests\NewsletterStoreRequest;
use App\Models\Newsletter;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;

class NewsletterController extends Controller

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    
        //
    

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    
    

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(NewsletterStoreRequest $request)
    
        return response()->json([
            'message' => 'suss',
        ]);
    

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    
        //
    

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    
        //
    

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    
        //
    

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    
        //
    

请求文件

NewsletterStoreRequest.php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class NewsletterStoreRequest extends FormRequest

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    
        return true;
    

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    
        return [
            'email' => ['required', 'max:150', 'email'],
        ];
    

路线

web.php

Route::post('/newsletter', [
    NewsletterController::class,
    'store',
])->name('newsletter.store');

在上面的示例中,我返回一个 json 对象,该对象不被接受并给我这个错误

我已经尝试按照关于响应here 的惯性文档进行操作,我认为在那里可以找到正确的答案,我自己无法解决它

我还研究了惯性 Jetstream 文档,但运气不佳 here

我不想返回一个新视图,我实际上希望它作为一个 ajax 请求工作p>

我看到很多人都有这个问题,有谁知道出了什么问题以及我必须在控制器中返回什么?

【问题讨论】:

【参考方案1】:

对我来说,我不得不将控制器更改为:

namespace App\Http\Controllers;

use Inertia\Inertia;
use App\Models\Newsletter;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use App\Http\Requests\NewsletterStoreRequest;

class NewsletterController extends Controller

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    
        //
    

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    
    

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(NewsletterStoreRequest $request)
    
        Newsletter::create([
            'email' => $request->email
        ]);

        return back()->with('flash', [
            'message' => 'success',
        ]);
    

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    
        //
    

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    
        //
    

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    
        //
    

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    
        //
    

这里你应该注意的是这部分:

    return back()->with('flash', [
        'message' => 'success',
    ]);

我找到了一个示例,在我的朋友的帮助下解决了我的问题:vendor/laravel/jetstream/src/Http/Controllers/Inertia/ApiTokenController.php

在这里他们返回一个像我上面的例子一样的 flash 消息,消息键将在 props->components->flash->message 中

它不会像我想象的 ajax 那样工作,因为它使用 Vue 路由,所以页面会在提交时重新加载。

我希望有人会觉得这很有用。

此外,如果您因为在 vue 组件中使用数据而收到控制台错误,则必须检查包装器以检查数据是否为空,如下所示:

<ul
   v-if="assets != null"
   class="
   marketcap-rows
   border-l border-r border-gray-200
   flex flex-col
   "
   >
   <li
      v-for="asset in $props.assets.data"
      v-bind:key="asset"
      class="
      bg-white
      grid
      gap-4
      border-t border-gray-200
      "
      >
   </li>
</ul>

这就是我说的支票:v-if="assets != null"

【讨论】:

【参考方案2】:

这是访问jetstream初始默认flash消息的方法:

session()->flash('flash',  [
    'bannerStyle'=> 'danger',
    'banner' => 'this is the first message',
]);
return Inertia::render('Admin/Overview', [
    'users'
]);

【讨论】:

【参考方案3】:

您需要将其添加到您的渲染中...

文档:https://inertiajs.com/shared-data#flash-messages

class HandleInertiaRequests extends Middleware
    
        public function share(Request $request)
        
            return array_merge(parent::share($request), [
                'flash' => [
                    'message' => fn () => $request->session()->get('message')
                ],
            ]);
        
    

【讨论】:

以上是关于Laravel 8 Jetstream Inertia 所有 Inertia 请求都必须收到有效的 Inertia 响应的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 laravel 8 +jetstream + spatie 为注册用户分配角色

Laravel 8 Jetstream:无法使用使用工厂和播种机播种的帐户登录

Jetstream 与 Liviwere - Laravel 8 - 运行 npm install 时的节点漏洞

在 Laravel 8 Jetstream 的 Blade 组件中绑定 Livewire 属性

CSS 不会在 XAMPP 上的 Laravel 8 + Jetstream 中加载

带有社交名流头像的 Laravel 8 Jetstream 个人资料照片