We have the following call to fetch
.
this.http.fetch('flasher', { method: 'post', body: jsonPayload })
.then(response => response.json())
.then(data => console.log(data));
This works when we receive a 200 response but logs nothing to the console when we receive a 500 response. How do we handle a 500?
asked Mar 25, 2016 at 18:35
Shaun LuttinShaun Luttin
131k79 gold badges400 silver badges466 bronze badges
2
Working Solution
Combining then
with catch
works.
fetch('http://some-site.com/api/some.json')
.then(function(response) { // first then()
if(response.ok)
{
return response.text();
}
throw new Error('Something went wrong.');
})
.then(function(text) { // second then()
console.log('Request successful', text);
})
.catch(function(error) { // catch
console.log('Request failed', error);
});
Details
fetch()
returns a Promise
containing a Response
object. The Promise
can become either fulfilled or rejected. Fulfillment runs the first then()
, returns its promise, and runs the second then()
. Rejection throws on the first then()
and jumps to the catch()
.
References
MDN — Promise
MDN — Checking that the fetch was successful
Google — Introduction to Fetch
answered Mar 25, 2016 at 19:02
Shaun LuttinShaun Luttin
131k79 gold badges400 silver badges466 bronze badges
2
Just try to wrap in an object like console.log({data})
Fedor
16.2k10 gold badges39 silver badges125 bronze badges
answered Jan 13 at 7:22
29.05.2020, 14:11 |
|||
|
|||
ошибка 500 fetch Здравствуйте, возникла проблема. Я написал форму регистрации, которая успешно работает, после чего написал js файл, который обращается к серверу через fetch GET методом и всё ок. Но когда я сделал форму логина и повторил всё уже с методом POST, то сервер выдаёт ошибку 500, причём сама форма логина работает, однако если подключить js файл с fetch то случается error. Есть идеи с чем это может быть связано? <!DOCTYPE HTML> <html> <head> <title>Login</title> </head> <body> <form method="POST" action="https://test-publicapi.maximarkets.org/Account/logon"> <p> <label>Login<br> <input name="email" type="email" size="40" id="log"> </label> </p> <p> <label>Password<br> <input name="password" type="password" size="40" id="pass"> </label> </p> <p> <button type="submit">Вход</button> </p> </form> <script src="scriptforlog.js"></script> </body> </html> Вот js файл async function onFormSubmit(evt) { evt.preventDefault(); let email = document.getElementById('log').value; let password = document.getElementById('pass').value; let skip2Fa = true; let data = new FormData(); data.append('email',email); data.append('password',password); data.append('skip2Fa',skip2Fa); const response = await fetch(`https://test-publicapi.maximarkets.org/Account/logon`, { method: "POST", body: data }); if(response.ok) { alert('ok'); } else { alert('wrong'); }; } const form = document.querySelector('form'); form.addEventListener('submit' , onFormSubmit); |
30.05.2020, 02:49 |
||||
|
||||
Вы отправляете данные в разных форматах — когда отправляли напрямую через форму, то там был тип application/x-www-form-urlencoded, (такой же, как у текстового представления класса URLSearchParams), что очевидно принимается сервером. А класс FormData в конечном счёте представляет данные при отправке в виде типа multipart/form-data, а вам нужен application/x-www-form-urlencoded. Можно перевести из одного формата в другой, а можно сразу правильный. Например, замените (строка №8) FormData на URLSearchParams. |
30.05.2020, 13:19 |
|||
|
|||
Спасибо, я уже понял что проблема была в формате данных, однако я решил проблему таким способом(добавил headers) function onFormSubmit(evt) { evt.preventDefault(); let mail = document.getElementById('log').value; let pass = document.getElementById('pass').value; fetch('https://test-publicapi.maximarkets.org/Account/logon', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ email: mail, password: pass, }) }); } const form = document.querySelector('form'); form.addEventListener('submit' , onFormSubmit); |
30.05.2020, 17:09 |
||||
|
||||
А чем смешанный тип не подойдет? Статус 500, это в первую очередь нужно смотреть логи на сервере и устранять причину на нем. |
04.06.2020, 01:53 |
||||||||||||||||||||
|
||||||||||||||||||||
Пусть имеется адрес «dimityr.novakov@gmil.com» и пароль «anybody!has@got#to$learn%sometime», которые нужно передать на сервер. Давайте посмотрим, как можно представить эти данные для передачи…
Т. к. передача файлов не нужна в данном случае, то наверно следует отдавать предпочтение менее многословному формату!
Многие общественные API могут такое возвращать, однако это скорей означает, что следует посылать данные в правильном формате. |
04.06.2020, 07:09 |
||||
|
||||
Ой ли так это на самом деле? И остальное ну чушь полнейшая, ибо на то он и смешанный тип, и он никак не может стать причиной ошибки отправки им вместо application/x-www-form-urlencoded. |
04.06.2020, 09:24 |
||||||||||||
|
||||||||||||
Какие предъявы? Посчитай байты!
Конечно же можешь посылать данные во всех возможных форматах, однако разработчики серверного кода могли написать только обработку, например, для типа json, а на всё остальное завершение со статусом 404 или 500 или найди ещё «Я — чайник!» или ещё что!
«Не хотим принимать такое — завершили как смогли!» |
04.06.2020, 09:53 |
|||
|
|||
Слушай, гений ты наш, ты практически ответил на возможную причину ошибки тем, что вместо application/x-www-form-urlencoded отдается тип multipart/form-data, что является просто бредом. Все дальнейшие твои рассказы, это пересказ документации, которую я и без тебя знаю. И хотя бы поинтересовался каковы причины могут порождать статус 500, и корректно ли будет бездумно при этом выплевывать его клиенту, пусть мается в догадках. А то гонишь пургу, баз какой-то беспредметный. |
04.06.2020, 10:26 |
||||||||||||
|
||||||||||||
Вам уже отвечали — неверный формат данных запроса. А чём вам не подходит ответ в формате JSON?
Я писал про отправку на сервер в формате multipart/form-data (и автор темы тоже), а не про отправку клиенту, которая кстати, происходит в формате JSON. И отправка клиенту статуса 500, а также сопутствующих данных тоже происходит в формате JSON… { "errorType": 1, "statusCode": 500, "message": "Processing of the HTTP request resulted in an exception. Please see the HTTP response returned by the 'Response' property of this exception for details.", "messageDetail": null, "validationErrors": null, "padString": null }
Какой пересказ? Даже автор темы давно понял, что «проблема была в формате данных». |
04.06.2020, 10:38 |
||||
|
||||
Значит так: если речь об API, то нормальный разработчик обязательно опишет параметры запроса, иначе, что вполне естественно, с API нельзя будет работать. В том что такое случилось скорее вина пользователя не удосужившегося прочесть документацию, и обнаружившего решение методом научного тыка. Ты же начал совсем с иного, что вообще никоим образом не могло быть источником проблемы. Все остальное, это ради поболтать. PS. Кстати, отвечать клиенту статусом 404 на ошибку несоответствия типу, это вообще из рук вон.
|
Quiz: What does this call to the web’s new fetch()
API do?
fetch("http://httpstat.us/500")
.then(function() {
console.log("ok");
}).catch(function() {
console.log("error");
});
If you’re like me, you might assume this code logs “error” when run—but it actually logs “ok”.
This expectation probably comes from years of jQuery development, as jQuery’s ajax()
method invokes its fail
handler when the response contains a failed HTTP status code. For example, the code below logs “error” when run:
$.ajax("http://httpstat.us/500")
.done(function() {
console.log("ok");
}).fail(function() {
console.log("error");
});
Why does fetch()
work this way?
Per MDN, the fetch()
API only rejects a promise when a “network error is encountered, although this usually means permissions issues or similar.” Basically fetch()
will only reject a promise if the user is offline, or some unlikely networking error occurs, such a DNS lookup failure.
The good is news is fetch
provides a simple ok
flag that indicates whether an HTTP response’s status code is in the successful range or not. For instance the following code logs “Error: Internal Server Error(…)”:
fetch("http://httpstat.us/500")
.then(function(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}).then(function(response) {
console.log("ok");
}).catch(function(error) {
console.log(error);
});
To keep this code DRY and reusable, you probably want to create a generic error handling function you can use for all of your fetch()
calls. The following code refactors the error handling into a handleErrors()
function:
function handleErrors(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}
fetch("http://httpstat.us/500")
.then(handleErrors)
.then(function(response) {
console.log("ok");
}).catch(function(error) {
console.log(error);
});
For added fun you can use ES6 arrow functions to make the callback formatting a little less verbose:
function handleErrors(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}
fetch("http://httpstat.us/500")
.then(handleErrors)
.then(response => console.log("ok") )
.catch(error => console.log(error) );
Parting thoughts
Although I still don’t like fetch()
’s lack of rejecting failed HTTP status codes, over time fetch()
’s behavior has grown on me—mostly because it gives me more control over how I handle individual problems. Plus, the composable nature of fetch()
makes it fairly trivial to manually handle errors without adding a bunch of verbose code.
Overall I think it’s worth taking few minutes to play with fetch()
, even if it’s just to see what you think. It’s certainly a far more readable alternative to XMLHttpRequest. If you happen to be building NativeScript apps, you might not know that you can use fetch()
today without any need for a polyfill or fallback. And something about using fetch()
to perform HTTP requests in native Android and iOS apps is just plain cool
This article was updated on September 15th, 2015 to use a simpler handleErrors()
function based on a comment from Jake Archibald.
Edit: FIXED — No 500 with HTTPS and working SSL, fixed and working in a minimal repo as below by adding this to either .env or to the npm dev script:
.env
NODE_TLS_REJECT_UNAUTHORIZED=0
Others discussed adding —host 0.0.0.0 as a loop back for an IPv6 issue (way over my head). I tried that and works fine. When I remove that host param or set it to anything else (e.g. something arbitrary like banana.test) and reload browser after full quit, I can still get SSL. So, that’s great. Hoping 500 fetch error gone in full.
So, SSL/HTTPS is working with rc13 and Node v18 with the above .env setting (or in script).
Nuxt3 authors seemed to suggest that you wouldn’t need the above line in I think RC11 or 12 but seems still needed for me. Hoping this helps someone else. Also cert made with mkcert. Both definition in dev script and in nuxt.config needed for me for SSL.
Original:
Same 500 fetch error. Fresh nuxt-rc13. Nothing else in it.
I’m wondering if anyone knows if I’m making a mistake on SSL / Certificate syntax in either config or package.json?
The error for me could be related to Node v18 (haven’t downgraded yet) or due to something else related to SSL cert.
I tried with variations on the dev script, e.g. —host 127.0.0.1 or localhost or blank, same error. When I remove the cert and cert-keys in dev script, no 500 error (Nuxt splash loads correctly) but now HTTP not HTTPS (SSL not accepted).
The config below is being accepted by Chrome for HTTPS.
Node: 18.7.0
500
fetch failed ()
at async $fetchRaw2 (/C:/code/nuxt3-b/node_modules/ohmyfetch/dist/shared/ohmyfetch.d1948a88.mjs:144:20)
at async /C:/code/nuxt3-b/.nuxt/dev/index.mjs:550:20
at async /C:/code/nuxt3-b/.nuxt/dev/index.mjs:624:64
at async /C:/code/nuxt3-b/.nuxt/dev/index.mjs:107:22
at async Object.handler (/C:/code/nuxt3-b/node_modules/h3/dist/index.mjs:634:19)
at async toNodeHandle (/C:/code/nuxt3-b/node_modules/h3/dist/index.mjs:698:7)
at async Object.ufetch [as localFetch] (/C:/code/nuxt3-b/node_modules/unenv/runtime/fetch/index.mjs:9:17)
at async Object.errorhandler [as onError] (/C:/code/nuxt3-b/.nuxt/dev/index.mjs:432:30)
at async Server.toNodeHandle (/C:/code/nuxt3-b/node_modules/h3/dist/index.mjs:705:9)
nuxt.config.ts
const fs = require('fs');
import {fileURLToPath} from "node:url";
export default defineNuxtConfig({
devServer: {
host: 'banana.test',
https: {
key: fs.readFileSync(fileURLToPath(new URL('./banana.test+4-key.pem', import.meta.url))),
cert: fs.readFileSync(fileURLToPath(new URL('./banana.test+4.pem', import.meta.url))),
}
},
})
package.json
{
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev --https --host banana.test --ssl-cert banana.test+4.pem --ssl-key banana.test+4-key.pem",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"devDependencies": {
"nuxt": "3.0.0-rc.13"
}
}
SSL works in the above config (HTTPS accepted) and I get the 500 error.
With just dev: nuxt dev --https --host banana.test
or any other params (excluding cert and cert-key), no 500, no HTTPS, and Nuxt splash loads correctly.
If anyone has any suggestions, much appreciated.
Здравствуйте. Делал форму с отправкой по одному видео. Phpmailer стоит последний,php на хостинг последней версии. Проверял, но бесполезно: выдает слово «Ошибка» из файла php и следующее в консоли:
Жалуется на эту строку в js-файле:
Мой код с каждого файла:
HTML
<div id="contact" class="FormBack">
<div class="form">
<!-- форма конечно будет отправляться за счет JS - action не
нужен, но ставим его с заглушкой, что ВАЛИДАТОР правильно работал-->
<div class="Smart"></div>
<div class="Smart2"></div>
<form action="#" id="form" class="form_body">
<h1 class="form_title">Отправить нам сообщение</h1>
<div class="form_item">
<!-- label будет привязан к formName -->
<label for = "formName" class="form_label">Имя:</label>
<input id="formName" type="text" name="Name" class="form_input _Req">
</div>
<div class="form_item">
<label for = "formEmail" class="form_label">E-mail:</label>
<input id="formEmail" type="text" name="Email" class="form_input _Req _Email">
</div>
<div class="form_item">
<label for = "formMessage" class="form_label">Сообщение:</label>
<textarea name="Message" id="formMessage" class="form_input _Req"></textarea>
</div>
<div class="form_item">
<div class="checkbox">
<input id="formAgree" type="checkbox" name="Agree" class="checkbox_input _Req">
<label for = "formAgree" class="checkbox_label"><span>Я даю свое согласие на обработку моих персональных данных</span></label>
</div>
</div>
<button type="submit" class="form_button"></button>
</form>
</div>
</div>
В js во второй части кода прописана валидация, если что
JavaScript
document.onreadystatechange = function(){
//Перехват формы отправки после нажатия кнопки
const form = document.getElementById('form');
//Вешаю событие submit на эту переменную
//и как отправив форму - переходим к formSend
form.addEventListener('submit', formSend);
async function formSend(Er)
{
//Запрет стандартной отправки(без заполнения)
Er.preventDefault();
//Теперь пропишем в js - что ДОЛЖНО выполняться
//после отправки
//ВАЛИДАЦИЯ
let Error = formValidate(form);
//Получаем все данные заполненных полей
let formData = new FormData(form);
//За счет AJAX(fetch) будем делать отправку данных
if(Error === 0){
//Как стало ясно, что ошибок нет - добавляем к форме
//класс _sending и СООБЩАЕМ ПОЛЬЗОВАТЕЛЮ ОБ
form.classList.add('_sending');
//В переменную response помещаем ожидание выполнения
//ОТПРАВКИ в файл php методом POST и данных formData
let Response = await fetch('sendmail.php',{
method: 'POST',
body: formData
});
//Проверка на успешность отправки данных
//sendmail будет возвращать JSON-ответ
//и в случае успеха - будем получать то,
//что в if
if(Response.ok){
let Result = await Response.json();
alert(Result.Message);
//После отправки формы - чистим ее
form.reset();
//Убираем высвечивание загрузки
form.classList.remove('_sending');
}
else{
alert("Ошибка");
//Просто убираем этот класс в случае
//ошибки, чтоб загрузка не вылезла
form.classList.remove('_sending');
}
//Если Error не равно нулю - что выводить
}
else{
alert('Заполнить обязательные поля!');
}
}
function formValidate(form){
let Error = 0;
//Класс req испольузем для проверки полей и добавл в html
let formReq = document.querySelectorAll('._Req');
//Создаем цикл, чтобы бегать по объектам, которым задали
//класс req для проверки
for (let index = 0; index < formReq.length; index++){
//Объект input помещается в константу input
const input = formReq[index];
//Изначально перед проверкой убираем класс Error
formRemoveError(input);
//Сама проверка
//У каждого поля будет своя проверка и потому у всех разные классы
if(input.classList.contains('_Email')){
//Если тест не пройден
if (EmailTest(input)){
formAddError(input);
//Увеличиваем error на единицу
Error++;
}
}
//Наличие проверки checkbox
//Проверка, что чекбокс и если бокс не включен
else if (input.getAttribute("type") === "checkbox" && input.checked === false){
//И вешаем на класс и его родителя ошибку
formAddError(input);
Error++;
}
else {
//Если поле пустое, то
if(input.value === ''){
formAddError(input);
Error++;
}
}
}
//Возвращаем значение нуля
return Error;
}
//1 Функция для добавления объекту класса Error
// и родительскому тоже(чтоб вместе горели красным)
//2 функция наоборот УБИРАЕТ этот класс
function formAddError(input){
input.parentElement.classList.add('_Error');
input.classList.add('_Error');
}
function formRemoveError(input){
input.parentElement.classList.remove('_Error');
input.classList.remove('_Error');
}
//Тест email
function EmailTest(input){
return !/^([A-Za-z0-9_-.])+@([A-Za-z0-9_-.])+.([A-Za-z]{2,4})$/.test(input.value);
}
}
PHP
<?php
//Загрузка необходимых файлов PHPMailer'а
use PHPMailerPHPMailerPHPMailer;
use PHPMailerPHPMailerException;
require 'phpmailer/src/Exception.php';
require 'phpmailer/src/PHPMailer.php';
//Объявляем PHPMailer
$mail = new PHPMailer(true);
//Настройка кодировки
$mail->CharSet = 'UTF-8';
//Языковой файл из папки PHPMailer(ошибки поймем тоже)
$mail->setLanguage('ru', 'phpmailer/language/');
//Включение html-тэгов в письме
$mail->IsHTML(true);
$mail->SMTPDebug = 2;
//От кого
$mail->setFrom('NoName@gmail.com', '');
//Кому
$mail->addAddress('icaab2608@gmail.com');
//Тема
$mail->Subject = 'Ваш сайт был кем-то замечен!';
//Тело письма
$body = '<h1>Неожиданно!Не правда ли?</h1>';
//Проверки полей на пустоту (на всякий)
if(trim(!empty($_POST['Name']))){
$body.='<p><strong>Имя: </strong> '.$_POST['Name'].'</p>';
}
if(trim(!empty($_POST['Email']))){
$body.='<p><strong>E-mail: </strong> '.$_POST['Email'].'</p>';
}
if(trim(!empty($_POST['Message']))){
$body.='<p><strong>Сообщение: </strong> '.$_POST['Message'].'</p>';
}
$mail->$body;
//Отправка
//Если форма не отправилась - выводит ошибку
if (!$mail->send()){
$Message = 'Ошибка';
}
else
{
$Message = 'Данные отправлены';
}
//Формирование JSON для присваивания сообщения
//что должно выводится при отправки
//и чтоб мы получили в ответ нужное сообщение
$Response = ['Message' => $Message];
header('Content-type: application/json');
//Возвращаем в JS с заголовком json
echo json_encode($Response);
error_reporting(E_ALL);
ini_set('display_errors', 1);
?>
Может правила оформления phpmailer поменялись и я отстал от жизни? (хостинг использую handyhost)
Еще в журнале ошибок нашел код hex, который на выходе дает следующее:
-
Вопрос заданболее года назад
-
227 просмотров
Пригласить эксперта
выдает слово «Ошибка» из файла php
Нет. Пых у вас падает в 500. А слово выдает
alert("Ошибка");
Смотрите логи пыха. Например, он мог не найти те файлы, что в require с относительным путем.
Или ему не нравится, что сначала use, а потом — откуда брать классы для этого use.
Брат. как по итогу решил проблему с fetch? У меня выходит подобная ошибка и все что возможно было, я проверил. Вдруг я какой подводный камень не увидел
-
Показать ещё
Загружается…
04 июн. 2023, в 01:35
1500 руб./за проект
04 июн. 2023, в 01:25
40000 руб./за проект
03 июн. 2023, в 23:42
1500 руб./за проект