【发布时间】:2019-11-15 10:33:46
【问题描述】:
当我尝试在前端使用 fetch 并在后端使用快速路由发送发布请求时,我收到了 TypeError: Failed to fetch 错误。
我能够在数据库中成功创建新用户,但是当尝试通过 fetch promise 获取新用户数据时,就会抛出错误。
app.js
function createNewUser() {
let formUsername = document.getElementById('signup-username').value;
let formEmail = document.getElementById('signup-email').value;
let formPassword = document.getElementById('signup-password').value;
let url = "/users";
let newUserData = {
username: formUsername,
email: formEmail,
password: formPassword
}
fetch(url, {
method: 'POST',
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
},
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer',
body: JSON.stringify(newUserData),
}).then(res => res.json())
.then(response => console.log('Success: ', JSON.stringify(response)))
.catch(error => console.error('Error: ', error));
}
users.js
router.post('/users', function(req, res) {
User.create(req.body)
.then(function(user) {
res.json({
user: user
})
}
});
server.js
const express = require('express');
const app = express();
const fs = require('fs');
const path = require('path');
const bodyParser = require('body-parser');
const bcrypt = require('bcryptjs');
const auth = require('./auth');
const router = require('./routes/routes.js');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(router);
app.use('/', express.static(path.join(__dirname, 'public')));
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Methods",
"OPTIONS, GET, POST, PUT, PATCH, DELETE" // what matters here is that OPTIONS is present
);
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization", "Access-Control-Allow-Origin");
next();
});
app.listen(3000, function(){
console.log("Listening on port 3000");
});
我需要取回该用户对象才能访问其数据。
编辑:
所以,我发现问题与如何在前端提交请求有关。如果我创建以下函数,然后在加载 app.js 时调用它,那么一切正常:
function createNewUserTest() {
let formUsername = 'dd';
let formEmail = 'd@d.com';
let formPassword = 'secrete';
let url = "/api/users";
let newUserData = {
username: formUsername,
email: formEmail,
password: formPassword
}
fetch(url, {
method: 'POST',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(newUserData),
})
.then(res => res.json())
.then(response => console.log('Success: ', response))
.catch(error => console.error('Error: ', error));
}
createNewUserTest();
但是,如果我尝试通过表单中的onsubmit 或html 中按钮上的onclick 调用此函数,或者如果我使用事件侦听器(见下文,位于app.js 中),然后我得到TypeError: Failed to fetch 错误:
let signupSubmitButton = document.getElementById('signup-submit');
signupSubmitButton.addEventListener('click', createNewUserTest);
这对我来说更加莫名其妙。我需要使用Vanilla JS,我需要通过表单提交来创建用户,但不确定我需要在这里调整什么。
解决方案
再次被event.preventDefault() 挫败。这就是我所需要的。
let signupForm = document.getElementById('signup-form');
signupForm.addEventListener('submit', function(event) {
event.preventDefault();
let formUsername = document.getElementById('signup-username').value;
let formEmail = document.getElementById('signup-email').value;
let formPassword = document.getElementById('signup-password').value;
let url = "/api/users";
let newUserData = {
username: formUsername,
email: formEmail,
password: formPassword
}
fetch(url, {
method: 'POST',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(newUserData),
})
.then(res => res.json())
.then(response => console.log('Success: ', response))
.catch(error => console.error('Error: ', error));
});
【问题讨论】:
-
同源请求不需要 CORS...我想这就是它抛出的原因,考虑到您的服务器不会使用 CORS 标头响应。
-
@PatrickRoberts 感谢您的回复!尝试删除
mode: 'cors',但我仍然遇到同样的错误。 -
"Access-Control-Origin",正确命名为 Access-Control-Allow-Origin,是一个 response 标头,应该从服务器发送到客户,而不是相反。
-
@Bergi 我将
server.js代码添加到我的初始请求中。我还删除了 CORS 属性,并从我的headers对象中删除了"Access-Control-Origin",但仍然出现相同的错误。 -
嗯,更新后的代码看起来应该可以工作了。您要在哪个域上运行它? devtools 对网络请求有什么看法?
标签: javascript node.js express fetch