v-on 处理程序变量 this 中的 VueJS 错误。未定义
VueJS Error in v-on handler variable this. is undefined
在具有 MongoDB/Express 后端 api 的 VueJS 中工作,尝试使用单个字段 url
添加 post 新记录到书签模型,但出现错误我试图传递的 url 字段是 undefined
。我之前已经将此模式用于 api 调用,没有遇到任何问题,所以我不确定这次发生了什么。
从控制台:
Error in v-on handler (Promise/async): "Error: Request failed with status code 500"
在网络选项卡中:
{"errors":{"message":"Cannot read property 'url' of undefined","error":{}}}
这里是组件:
<template>
<div class="bookmarks">
<h1>Add a Bookmark</h1>
<div class="form">
<div>
<input type="text" placeholder="Enter a URL" v-model="url">
</div>
<div>
<button class="app_post_btn" @click="addBookmark">Save</button>
</div>
</div>
</div>
</template>
<script>
import BookmarksService from '@/services/BookmarksService'
export default {
name: 'NewBookmark',
data () {
return {
url: ''
}
},
methods: {
async addBookmark () {
await BookmarksService.addBookmark({
url: this.url
})
this.$router.push({ name: 'Bookmarks' })
}
}
}
</script>
<style type='text/css'>
.form input,
.form textarea {
width: 500px;
padding: 10px;
border: 1px solid #e0dede;
outline: none;
font-size: 12px;
}
.form div {
margin: 20px;
}
.app_post_btn {
background: #4d7ef7;
color: #fff;
padding: 10px 80px;
text-transform: uppercase;
font-size: 12px;
font-weight: bold;
width: 520px;
border: none;
cursor: pointer;
}
</style>
对后端的 api 调用来自服务文件夹,因此在 BookmarksService.js:
import Api from '@/services/Api'
export default {
fetchBookmarks () {
return Api().get('bookmarks')
},
addBookmark (params) {
return Api().post('bookmarks', params)
}
...
Api.js:
import axios from 'axios'
const token = localStorage.getItem('token')
export default () => {
return axios.create({
baseURL: 'http://localhost:8000/api',
headers: {
'Content-Type': 'application/json',
token: token,
}
})
}
为了回应下面的评论,这里是请求信息:
Request URL: http://localhost:8000/api/bookmarks
Request Method: POST
Status Code: 500 Internal Server Error
Remote Address: [::1]:8000
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 75
Content-Type: application/json; charset=utf-8
Date: Fri, 05 Apr 2019 16:47:01 GMT
ETag: W/"4b-DnvHolHvXjMbxmLeqrleWSWRA0Q"
X-Powered-By: Express
Provisional headers are shown
Accept: application/json, text/plain, */*
authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InVzZXJvbmVAZ21haWwuY29tIiwiaWQiOiI1YzlmOTcxY2E3YzIyNTc1ZTFjYzkwMDUiLCJleHAiOjE1NTk2NjY3ODcsImlhdCI6MTU1NDQ4Mjc4N30.zlrqFfj2r7K_1iAVm7m2w_kUeqFH3ZvsDJkIK7UOUu8
Content-Type: application/json
Origin: http://localhost:8080
Referer: http://localhost:8080/
token: Token undefined
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
{url: "http://axios.com"}
url: "http://axios.com"
在服务器端:
这是 post 路线:
const mongoose = require('mongoose');
const passport = require('passport');
const router = require('express').Router();
const auth = require('../auth');
const Bookmarks = mongoose.model('Bookmarks');
//POST new user route (optional, everyone has access)
router.post('/', auth.required, (req, res, next) => {
const userId = req.user.id;
const bookmark = req.body.bookmark;
if(!bookmark.url) {
return res.status(422).json({
errors: {
url: 'is required',
},
});
}
bookmark.userId = userId;
const finalBookmark = new Bookmarks(bookmark);
return finalBookmark.save()
.then(() => res.json({ bookmark: finalBookmark }));
});
...
来自 Express 应用程序的 app.js 文件:
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const session = require('express-session');
const cors = require('cors');
const mongoose = require('mongoose');
const errorHandler = require('errorhandler');
//Configure mongoose's promise to global promise
mongoose.promise = global.Promise;
//Configure isProduction variable
const isProduction = process.env.NODE_ENV === 'production';
//Initiate our app
const app = express();
//Configure our app
app.use(cors());
app.use(require('morgan')('dev'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({ secret: 'bookmarks-darius', cookie: { maxAge: 60000 }, resave: false, saveUninitialized: false }));
if(!isProduction) {
app.use(errorHandler());
}
//Configure Mongoose
mongoose.connect('mongodb://localhost/bookmarks', { useNewUrlParser: true });
mongoose.set('debug', true);
//Models & routes
require('./models/Users');
require('./models/Bookmarks');
require('./config/passport');
app.use(require('./routes'));
// express doesn't consider not found 404 as an error so we need to handle 404 explicitly handle 404 error
app.use(function(req, res, next) {
if (err) {
next(err);
} else { // no error thrown by another route, so we must not have found a route, therefore return a 404
let err = new Error('Not Found');
err.status = 404;
next(err);
}
});
//Error handlers & middlewares
if(!isProduction) {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.json({
errors: {
message: err.message,
error: err,
},
});
});
}
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.json({
errors: {
message: err.message,
error: {},
},
});
});
app.listen(8000, () => console.log('Server running on http://localhost:8000/'));
请参阅下面的代码段。始终验证来自正文的任何 属性。
router.post('/', auth.required, (req, res, next) => {
const userId = req.user.id;
const bookmark = req.body.bookmark; <---- bookmark is undefined
if(!bookmark.url) { <---- undefined.url -> Error.
return res.status(422).json({
errors: {
url: 'is required',
},
});
}
// ...
});
来自您的前端的请求正文不是您所期望的。
这里的主要问题是,在 vue.js 组件的 addBookmark 函数中,您传递的对象只有 属性 'url',而在您的后端服务中,您期望的是 'bookmark' 对象,其中包含 属性 'url'。
您也可以在请求正文中看到它:{url: "http://axios.com"}
将您的组件代码更改为
async addBookmark () {
await BookmarksService.addBookmark({
bookmark: {
url: this.url
}
})
this.$router.push({ name: 'Bookmarks' })
}
应该可以。你应该得到这样的东西 { bookmark: {url: "http://axios.com"} }
。
无论如何验证来自请求正文的任何 属性 正如 Phil 所说始终是您应该遵循的好习惯。
在具有 MongoDB/Express 后端 api 的 VueJS 中工作,尝试使用单个字段 url
添加 post 新记录到书签模型,但出现错误我试图传递的 url 字段是 undefined
。我之前已经将此模式用于 api 调用,没有遇到任何问题,所以我不确定这次发生了什么。
从控制台:
Error in v-on handler (Promise/async): "Error: Request failed with status code 500"
在网络选项卡中:
{"errors":{"message":"Cannot read property 'url' of undefined","error":{}}}
这里是组件:
<template>
<div class="bookmarks">
<h1>Add a Bookmark</h1>
<div class="form">
<div>
<input type="text" placeholder="Enter a URL" v-model="url">
</div>
<div>
<button class="app_post_btn" @click="addBookmark">Save</button>
</div>
</div>
</div>
</template>
<script>
import BookmarksService from '@/services/BookmarksService'
export default {
name: 'NewBookmark',
data () {
return {
url: ''
}
},
methods: {
async addBookmark () {
await BookmarksService.addBookmark({
url: this.url
})
this.$router.push({ name: 'Bookmarks' })
}
}
}
</script>
<style type='text/css'>
.form input,
.form textarea {
width: 500px;
padding: 10px;
border: 1px solid #e0dede;
outline: none;
font-size: 12px;
}
.form div {
margin: 20px;
}
.app_post_btn {
background: #4d7ef7;
color: #fff;
padding: 10px 80px;
text-transform: uppercase;
font-size: 12px;
font-weight: bold;
width: 520px;
border: none;
cursor: pointer;
}
</style>
对后端的 api 调用来自服务文件夹,因此在 BookmarksService.js:
import Api from '@/services/Api'
export default {
fetchBookmarks () {
return Api().get('bookmarks')
},
addBookmark (params) {
return Api().post('bookmarks', params)
}
...
Api.js:
import axios from 'axios'
const token = localStorage.getItem('token')
export default () => {
return axios.create({
baseURL: 'http://localhost:8000/api',
headers: {
'Content-Type': 'application/json',
token: token,
}
})
}
为了回应下面的评论,这里是请求信息:
Request URL: http://localhost:8000/api/bookmarks
Request Method: POST
Status Code: 500 Internal Server Error
Remote Address: [::1]:8000
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 75
Content-Type: application/json; charset=utf-8
Date: Fri, 05 Apr 2019 16:47:01 GMT
ETag: W/"4b-DnvHolHvXjMbxmLeqrleWSWRA0Q"
X-Powered-By: Express
Provisional headers are shown
Accept: application/json, text/plain, */*
authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InVzZXJvbmVAZ21haWwuY29tIiwiaWQiOiI1YzlmOTcxY2E3YzIyNTc1ZTFjYzkwMDUiLCJleHAiOjE1NTk2NjY3ODcsImlhdCI6MTU1NDQ4Mjc4N30.zlrqFfj2r7K_1iAVm7m2w_kUeqFH3ZvsDJkIK7UOUu8
Content-Type: application/json
Origin: http://localhost:8080
Referer: http://localhost:8080/
token: Token undefined
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
{url: "http://axios.com"}
url: "http://axios.com"
在服务器端:
这是 post 路线:
const mongoose = require('mongoose');
const passport = require('passport');
const router = require('express').Router();
const auth = require('../auth');
const Bookmarks = mongoose.model('Bookmarks');
//POST new user route (optional, everyone has access)
router.post('/', auth.required, (req, res, next) => {
const userId = req.user.id;
const bookmark = req.body.bookmark;
if(!bookmark.url) {
return res.status(422).json({
errors: {
url: 'is required',
},
});
}
bookmark.userId = userId;
const finalBookmark = new Bookmarks(bookmark);
return finalBookmark.save()
.then(() => res.json({ bookmark: finalBookmark }));
});
...
来自 Express 应用程序的 app.js 文件:
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const session = require('express-session');
const cors = require('cors');
const mongoose = require('mongoose');
const errorHandler = require('errorhandler');
//Configure mongoose's promise to global promise
mongoose.promise = global.Promise;
//Configure isProduction variable
const isProduction = process.env.NODE_ENV === 'production';
//Initiate our app
const app = express();
//Configure our app
app.use(cors());
app.use(require('morgan')('dev'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({ secret: 'bookmarks-darius', cookie: { maxAge: 60000 }, resave: false, saveUninitialized: false }));
if(!isProduction) {
app.use(errorHandler());
}
//Configure Mongoose
mongoose.connect('mongodb://localhost/bookmarks', { useNewUrlParser: true });
mongoose.set('debug', true);
//Models & routes
require('./models/Users');
require('./models/Bookmarks');
require('./config/passport');
app.use(require('./routes'));
// express doesn't consider not found 404 as an error so we need to handle 404 explicitly handle 404 error
app.use(function(req, res, next) {
if (err) {
next(err);
} else { // no error thrown by another route, so we must not have found a route, therefore return a 404
let err = new Error('Not Found');
err.status = 404;
next(err);
}
});
//Error handlers & middlewares
if(!isProduction) {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.json({
errors: {
message: err.message,
error: err,
},
});
});
}
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.json({
errors: {
message: err.message,
error: {},
},
});
});
app.listen(8000, () => console.log('Server running on http://localhost:8000/'));
请参阅下面的代码段。始终验证来自正文的任何 属性。
router.post('/', auth.required, (req, res, next) => {
const userId = req.user.id;
const bookmark = req.body.bookmark; <---- bookmark is undefined
if(!bookmark.url) { <---- undefined.url -> Error.
return res.status(422).json({
errors: {
url: 'is required',
},
});
}
// ...
});
来自您的前端的请求正文不是您所期望的。
这里的主要问题是,在 vue.js 组件的 addBookmark 函数中,您传递的对象只有 属性 'url',而在您的后端服务中,您期望的是 'bookmark' 对象,其中包含 属性 'url'。
您也可以在请求正文中看到它:{url: "http://axios.com"}
将您的组件代码更改为
async addBookmark () {
await BookmarksService.addBookmark({
bookmark: {
url: this.url
}
})
this.$router.push({ name: 'Bookmarks' })
}
应该可以。你应该得到这样的东西 { bookmark: {url: "http://axios.com"} }
。
无论如何验证来自请求正文的任何 属性 正如 Phil 所说始终是您应该遵循的好习惯。