当我尝试使用前端的TypeError: Failed to fetch
和后端的快速路由发送发布请求时,出现fetch
错误。
我能够在数据库中成功创建新用户,但是当尝试通过访存承诺获取新用户数据时,就是在抛出错误时。
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
调用此函数,或者如果我使用事件监听器(请参见下文,位于{ {1}}),然后出现app.js
错误:
TypeError: Failed to fetch
这让我更加困惑。我需要使用Vanilla JS,并且需要通过提交表单来创建用户,但不确定在这里我需要调整什么。
解决方案
再次被let signupSubmitButton = document.getElementById('signup-submit');
signupSubmitButton.addEventListener('click', createNewUserTest);
搞砸了。这就是我所需要的。
event.preventDefault()
答案 0 :(得分:0)
涉及CORS问题时,通常是因为服务器不知道如何正确处理它。基本上,每当您在请求中包含诸如access-control-origin
之类的标头时,它也会引发OPTIONS预检请求,并且如果您的服务器不希望它会引发错误,因为它只希望POST请求。
换句话说-在没有"Access-Control-Origin": "*"
部分的情况下重试,看看它是否有效,或者尝试使用以下方法在服务器上对其进行修补:
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");
next();
});
答案 1 :(得分:0)
问题在于页面正在重新加载,这使我无法及时获取数据。解决方案是在听众内部简单地添加event.preventDefault()
。
app.js
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));
});
答案 2 :(得分:0)
问题与“ TypeError无法提取”有关。消息的措词向其他答复中探讨的网络/服务器/ CORS类型问题发送了一个消息,但是我发现有一个完全不同的原因。
我遇到了这个问题,并花了一段时间才发现它的价值,尤其是感到困惑,因为它是由我的页面在Chrome中发布而不是在Firefox中引起的。
直到我发现chrome:// net-internals /#events并看到我的请求受到'delegate_blocked_by =“ Opening Files”“的困扰后,我才终于有了端倪。
我的要求是发布一个通过文件输入元素从用户计算机上传的文件。该文件碰巧是在Excel中打开的文件。尽管它可以从Firefox发布,但只有在关闭后才能在Chrome中发布。
需要向您的Web应用程序的用户提供有关此潜在问题的建议,并且Web开发人员还应该意识到“ TypeError无法提取”有时可能意味着“ TypeError没有达到尝试获取的程度”