Ser
Ser

Reputation: 187

Laravel API: "POST http://localhost/api/post 419 (unknown status)" (Vue.js)

Im trying to make a post in a vue component with Laravel Api.

I got CSRF token in my welcome.blade.php:

<meta name="csrf-token" content="{{ csrf_token() }}">

Page does not refresh or add anything when i click on the button. If i click on the button i get this in my console:

POST http://localhost/api/post 419 (unknown status)


PostList.vue

<template>
    <div class="container py-4">
        <form enctype="multipart/form-data" method="post" action="" @submit.prevent="addPost">
            <input type="hidden" name="_token" value=""/>
            <div class="modal-header">
                <h4 class="modal-title">Create Post</h4>
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label>Title</label>
                    <input type="text" class="form-control" placeholder="Title" v-model="post.title">
                </div>
                <div class="form-group">
                    <label>Description</label>
                    <textarea class="form-control" placeholder="Body" v-model="post.body"></textarea>
                </div>
            </div>
            <div class="modal-footer">
                <input type="button" class="btn btn-default" data-dismiss="modal" value="Cancel">
                <input type="submit" class="btn btn-primary" value="Add">
            </div>
        </form>
    </div>
</template>


<script>
    export default {
        data() {
            return {
                post: {
                    id: '',
                    title: '',
                    body: ''
                }
            };
        },
        created() {
            this.getPosts();
        },
        methods: {
            addPost(){
                fetch('api/post', {
                    method: 'post',
                    body: JSON.stringify(this.post),
                    headers: {
                        'content-type': 'apllication/json'
                    }
                })
                    .then(response => response.json())
                    .then(data => {
                        this.getPosts();
                    })
                    .catch(err => console.log(err));
            }
        }
    };
</script>

PostController.php

public function store_vue(Request $request){
        $post = new Posts();
        $post->title = $request->get('title');
        $post->body = $request->get('body');
        $post->slug = Str::slug($post->title);

        $post->author_id = $request->user()->id;

        if ($post->save()) {
            return new PostResource($post);
        }
    }

Upvotes: 0

Views: 1308

Answers (2)

Basharmal
Basharmal

Reputation: 1384

Laravel has a middleware called VerifyCsrfToken which is enabled by default. It makes sure all POST requests have a csrf token. This tokens make sure the request is sent from our app only and not from any 3rd party scraper or form submiting tool.

When controller does not get _token in request, it throws error.
Add this 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') on header section in like belwo You can try this

 <script>
        export default {
            data() {
                return {
                    post: {
                        id: '',
                        title: '',
                        body: ''
                    }
                };
            },
            created() {
                this.getPosts();
            },
            methods: {
                addPost(){
                    fetch('api/post', {
                        method: 'post',
                        body: JSON.stringify(this.post),
                        headers: {
                            'content-type': 'apllication/json', 
                             'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                        }
                    })
                        .then(response => response.text())
                        .then(data => {
                            this.getPosts();
                        })
                        .catch(err => console.log(err));
                }
            }
        };
    </script>

Upvotes: 1

N69S
N69S

Reputation: 17216

You are getting a 419 error because the request is missing the CSRF token.

You can add it to your form and see if it works for you

<form enctype="multipart/form-data" method="post" action="" @submit.prevent="addPost">
    <input type="hidden" name="_token" value="{{ csrf_token() }}" />

OR

Add the header with the CSRF to your call

<script>
    export default {
        data() {
            return {
                post: {
                    id: '',
                    title: '',
                    body: ''
                }
            };
        },
        created() {
            this.getPosts();
        },
        methods: {
            addPost(){
                fetch('api/post', {
                    method: 'post',
                    body: JSON.stringify(this.post),
                    headers: {
                        'content-type': 'apllication/json',
                        'X-CSRF-TOKEN': document.querySelector("meta[property='csrf-token']").getAttribute("content");
                    }
                })
                    .then(response => response.json())
                    .then(data => {
                        this.getPosts();
                    })
                    .catch(err => console.log(err));
            }
        }
    };
</script>

Upvotes: 1

Related Questions