Je reçois une erreur TypeError: Failed to fetch
lorsque j'essaie d'envoyer une demande postale à l'aide de fetch
sur le front-end et un itinéraire express sur le back-end.
Je suis capable de créer avec succès le nouvel utilisateur dans la base de données, mais lorsque vous essayez d'obtenir cette nouvelle donnée d'utilisateurs via la promesse de récupération, c'est lorsque l'erreur est lancée.
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));
}
sers.js
router.post('/users', function(req, res) {
User.create(req.body)
.then(function(user) {
res.json({
user: user
})
}
});
serveur.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");
});
J'ai besoin d'obtenir cet objet d'utilisateur afin d'accéder à ses données.
Edit : Donc, j'ai compris que le problème a trait à la manière dont la demande est soumise sur le front-end. Si je crée la fonction suivante, appelez-la lorsque app.js
est chargé, tout fonctionne:
function createNewUserTest() {
let formUsername = 'dd';
let formEmail = '[email protected]';
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();
Mais si j'essaie d'appeler cette fonction via onsubmit
sous la forme ou onclick
sur le bouton du HTML, ou si j'utilise un auditeur d'événements (voir ci-dessous, ce qui est dans app.js
), alors je reçois l'erreur TypeError: Failed to fetch
:
let signupSubmitButton = document.getElementById('signup-submit');
signupSubmitButton.addEventListener('click', createNewUserTest);
C'est encore plus de dérangement pour moi. Je suis obligé d'utiliser Vanilla JS et je dois créer l'utilisateur via une soumission de formulaire, mais pas sûr de ce que je dois ajuster ici.
solution Feulée par le event.preventDefault()
à nouveau. C'était tout ce dont j'avais besoin.
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));
});
La question était que la page rechargée, ce qui m'a empêché de récupérer les données à temps. La solution consistait à ajouter simplement event.preventDefault()
à l'intérieur de l'auditeur.
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));
});
En ce qui concerne les problèmes de Cors, c'est très souvent parce que le serveur ne sait pas comment le gérer correctement. Fondamentalement, chaque fois que vous incluez une en-tête comme access-control-Origin
À votre demande, il incitera également les options Demande de préfixe et si votre serveur ne s'attend pas à ce qu'elle jette une erreur, car elle s'attendait à A POST seulement demandes.
En d'autres termes - essayez à nouveau sans le "Access-Control-Origin": "*"
Partie et voir si cela fonctionne ou essayez simplement de le corriger sur le serveur avec quelque chose comme ceci:
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();
});
La question concerne "TypeError a échoué à aller chercher". Le libellé du message envoie un dans la direction des problèmes de type réseau/serveur/Cors comme explorés dans d'autres réponses, mais il y a une cause que j'ai découverte qui est complètement différente.
J'ai eu ce problème et l'ai pris à la valeur de visage pendant un certain temps, particulièrement perplexe car elle a été provoquée par ma page en affectation de Chrome mais pas dans Firefox.
Ce n'est qu'après avoir découvert Chrome: // Net-interne/# Événements et a vu que ma demande a souffert de "délégué_blocked_by =" Fichiers d'ouverture "" que j'ai enfin eu une idée.
Ma requête postait un fichier téléchargé de l'ordinateur de l'utilisateur via un élément d'entrée de fichier. Ce fichier est arrivé à être un fichier ouvert à Excel. Bien que cela ait posté une amende de Firefox, ce n'était que lorsqu'il est fermé qu'il pourrait être affiché en chrome.
Les utilisateurs de votre application Web doivent être informés de ce problème potentiel et des développeurs Web doivent également être conscients que "TypeError n'a pas récupéré" peut parfois signifier "TypeError n'a pas eu pour essayer de chercher"