【发布时间】:2020-03-24 14:21:34
【问题描述】:
我正在将刀片文件中的表单切换为使用 axios 发布的基于 vue 的表单。我收到 200 响应,但我没有在控制器中点击我的 store() 方法。我用原始刀片形式击中它。到目前为止,我尝试过的事情是手动添加 csrf 令牌,将标头更改为内容类型多部分,将发布数据更改为 JSON 字符串,以及更改 handleSubmit 以触发表单。这些似乎都没有任何效果。
我的刀片文件包含 vue 表单
@extends('layouts.app')
@section('content')
<div class="container">
<create-post></create-post>
</div>
@endsection
createPost.vue
<template>
<div class="container">
<h4>create post</h4>
<form @submit.prevent="handleSubmit" action='/p' enctype="multipart/form-data" method="post">
<input type="hidden" name="_token" :value="csrf">
<section v-if='step == 1'>
<template v-for="(image, index) in images">
<image-uploader-field
v-if='image_count >= index + 1'
v-bind:field='image'
v-bind:index='index'>
</image-uploader-field>
</template>
<button
v-if='image_count < 5'
@click.prevent='addImage'>Add Another Image
</button>
</section>
<section v-if='step == 2'>
<h3>Auction Components</h3>
<div>
<label>starting bid $
<input type="number" min=".00" step=".01" v-model='starting_bid' placeholder='00.00' />
</label>
</div>
<div>
<label>bid increment $
<input type="number" min=".00" step=".01" v-model='bid_increment' placeholder='00.00'/>
</label>
</div>
<div>
end time
<datetime format="MM-DD-YYYY h:i:s" width="300px" v-model="end_time" ></datetime>
</div>
<div>
<label>BIN $
<input type="number" min=".00" step=".01" v-model='bin' placeholder='00.00'/>
</label>
</div>
<div>
<label>snipe
<input type='checkbox' v-model='snipe'/>
</label>
</div>
<div>
<label v-if="snipe != false">snipe time
<input type="number" min="1" step="any" v-model='snipe_time' /> minutes
</label>
</div>
<div>
<label>auto remove bids
<input type='checkbox' v-model='autoremove_bids'/>
</label>
</div>
</section>
<section v-if='step == 3'>
<h3>Write Caption</h3>
<textarea
v-model='caption'
placeholder='type your message'
class='form-control form-control-large'
rows="4"
cols="50">
</textarea>
</section>
<section v-if='step == 4'>
<h3>Preview</h3>
<h4 v-if='caption !=null'>profilename: {{caption}}</h4>
<h4 v-if='starting_bid !=null'>Starting Bid: ${{starting_bid}}</h4>
<h4 v-if='bid_increment !=null'>Bid Increment: ${{bid_increment}}</h4>
<h4 v-if='end_time !=null'>Auction ends at: {{end_time}}</h4>
<h4 v-if='bin !=null'>BIN: ${{bin}}</h4>
<h4 v-if='snipe_time !=null'>Snipe rule in effect: {{snipe_time}} minutes</h4>
</section>
<button
v-if='step !== 1'
@click.prevent='prevStep'>Previous</button>
<button
v-if='step !== totalsteps'
@click.prevent='nextStep'
v-text='nextText'></button>
<button
v-if='step == totalsteps'
type='submit'>Post</button>
</form>
</div>
</template>
<style scoped>
img{
max-height: 36px;
}
</style>
<script>
import datetime from 'vuejs-datetimepicker';
export default {
components: { datetime },
data: function () {
return{
image_count:1,
max_uploads:5,
totalsteps:4,
step:1,
images:[
{image_path:"", image_filters:[],},
{image_path:"", image_filters:[],},
{image_path:"", image_filters:[],},
{image_path:"", image_filters:[],},
{image_path:"", image_filters:[],},
],
caption:null,
starting_bid:null,
bid_increment:null,
end_time:null,
bin:null,
snipe:false,
snipe_time:null,
autoremove_bids:false,
csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
}
},
computed: {
nextText(){
if(this.step == 3){
return 'Preview'
} else {
return 'Next'
}
}
},
methods: {
nextStep: function()
{
this.step++;
},
prevStep: function()
{
this.step--;
},
addImage: function()
{
this.image_count++
},
handleSubmit: function()
{
const post_data = Object.entries(this._data);
axios.post('/p', post_data)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
},
onFileChange(e) {
let files = e.target.files || e.dataTransfer.files;
if (!files.length)
return;
this.createImage(files[0]);
},
createImage(file) {
let reader = new FileReader();
let vm = this;
reader.onload = (e) => {
vm.image = e.target.result;
};
reader.readAsDataURL(file);
},
editImage(){
alert('render image-editor here');
},
},
}
</script>
我在 web.php 中发帖的路径
Route::get('/p/create', 'PostsController@create');
Route::post('/p', 'PostsController@store');
我的postsController 中的store 方法,我设置了一个console.log 只是为了查看如果我正在点击它,它看起来我不是
class PostsController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function create()
{
return view('posts/create');
}
public function store()
{
console.log('hit store method');
//VALIDATES DATA
$data = request()->validate([
'caption' => 'required',
'image1' => ['required', 'image',],
'image2' => 'image',
'image3' => 'image',
'image4' => 'image',
'image5' => 'image',
]);
//CREATE IMAGES ARRAY AND UPLOADS TO S3
$imageArray = [];
$imageCount = 1;
foreach($data as $key => $value){
if (strpos($key, 'image') !== false) {
$imagePath = request('image' . $imageCount)->store('uploads', 's3');
$imageCount ++;
array_push($imageArray, 'https://instagrizzle-development.s3.amazonaws.com/' . $imagePath);
}
}
//Relational method HARDCODED profile
auth()->user()->profiles[0]->posts()->create([
'caption' => $data['caption'],
'image' => json_encode($imageArray),
]);
return redirect('/profile/' . auth()->user()->profiles[0]->id);
}
}
添加
action='/p' enctype="multipart/form-data" method="post"
到表单标签似乎是多余的,但我想我会尝试一下。也不确定,但 axios 默认会自动添加 csrf 令牌吗?任何帮助,将不胜感激。提前致谢
这是我提交表单后得到的回复 response image
【问题讨论】:
-
为什么你的 laravel 控制器中有一个
console.log('hit store method');? -
只是为了得到一些反馈,我确实在使用 store 方法
-
我有一个 dd(response());前。但由于我的提交按钮上有 .prevent,我想我可能看不到它
-
将其替换为
return 'ok' ;。console.log()是 javascript,它在 php 中不起作用 -
您可以尝试在 auth 中间件上方的控制器构造函数中使用 Log::info('') 或 dd()
标签: javascript php laravel vue.js laravel-blade