29.05.2020, 15: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, 03:49 |
||||
|
||||
Вы отправляете данные в разных форматах — когда отправляли напрямую через форму, то там был тип application/x-www-form-urlencoded, (такой же, как у текстового представления класса URLSearchParams), что очевидно принимается сервером. А класс FormData в конечном счёте представляет данные при отправке в виде типа multipart/form-data, а вам нужен application/x-www-form-urlencoded. Можно перевести из одного формата в другой, а можно сразу правильный. Например, замените (строка №8) FormData на URLSearchParams. |
30.05.2020, 14: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, 18:09 |
||||
|
||||
А чем смешанный тип не подойдет? Статус 500, это в первую очередь нужно смотреть логи на сервере и устранять причину на нем. |
04.06.2020, 02:53 |
||||||||||||||||||||
|
||||||||||||||||||||
Пусть имеется адрес «dimityr.novakov@gmil.com» и пароль «anybody!has@got#to$learn%sometime», которые нужно передать на сервер. Давайте посмотрим, как можно представить эти данные для передачи…
Т. к. передача файлов не нужна в данном случае, то наверно следует отдавать предпочтение менее многословному формату!
Многие общественные API могут такое возвращать, однако это скорей означает, что следует посылать данные в правильном формате. |
04.06.2020, 08:09 |
||||
|
||||
Ой ли так это на самом деле? И остальное ну чушь полнейшая, ибо на то он и смешанный тип, и он никак не может стать причиной ошибки отправки им вместо application/x-www-form-urlencoded. |
04.06.2020, 10:24 |
||||||||||||
|
||||||||||||
Какие предъявы? Посчитай байты!
Конечно же можешь посылать данные во всех возможных форматах, однако разработчики серверного кода могли написать только обработку, например, для типа json, а на всё остальное завершение со статусом 404 или 500 или найди ещё «Я — чайник!» или ещё что!
«Не хотим принимать такое — завершили как смогли!» |
04.06.2020, 10:53 |
|||
|
|||
Слушай, гений ты наш, ты практически ответил на возможную причину ошибки тем, что вместо application/x-www-form-urlencoded отдается тип multipart/form-data, что является просто бредом. Все дальнейшие твои рассказы, это пересказ документации, которую я и без тебя знаю. И хотя бы поинтересовался каковы причины могут порождать статус 500, и корректно ли будет бездумно при этом выплевывать его клиенту, пусть мается в догадках. А то гонишь пургу, баз какой-то беспредметный. |
04.06.2020, 11: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, 11: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.
Здравствуйте. Делал форму с отправкой по одному видео. 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, который на выходе дает следующее:
-
Вопрос заданболее года назад
-
192 просмотра
Пригласить эксперта
выдает слово «Ошибка» из файла php
Нет. Пых у вас падает в 500. А слово выдает
alert("Ошибка");
Смотрите логи пыха. Например, он мог не найти те файлы, что в require с относительным путем.
Или ему не нравится, что сначала use, а потом — откуда брать классы для этого use.
Брат. как по итогу решил проблему с fetch? У меня выходит подобная ошибка и все что возможно было, я проверил. Вдруг я какой подводный камень не увидел
-
Показать ещё
Загружается…
12 февр. 2023, в 21:32
80000 руб./за проект
12 февр. 2023, в 21:30
2900 руб./за проект
12 февр. 2023, в 21:30
7000 руб./за проект
Минуточку внимания
May 23, 2022
- Anticipate potential network errors
- Examples of user errors
- Examples of environmental changes
- Examples of errors with the video-sharing website
- Handle errors with the Fetch API
- When the Fetch API throws errors
- When the network status code represents an error
- When there is an error parsing the network response
- When the network request must be canceled before it completes
- Conclusion
This article demonstrates some error handling approaches when working with the Fetch API. The Fetch API lets you make a request to a remote network resource. When you make a remote network call, your web page becomes subject to a variety of potential network errors.
The following sections describe potential errors and describe how to write code that provides a sensible level of functionality that is resilient to errors and unexpected network conditions. Resilient code keeps your users happy and maintains a standard level of service for your website.
Anticipate potential network errors #
This section describes a scenario in which the user creates a new video named "My Travels.mp4"
and then attempts to upload the video to a video-sharing website.
When working with Fetch, it’s easy to consider the happy path where the user successfully uploads the video. However, there are other paths that are not as smooth, but for which web developers must plan. Such (unhappy) paths can happen due to user error, through unexpected environmental conditions, or because of a bug on the video-sharing website.
Examples of user errors #
- The user uploads an image file (such as JPEG) instead of a video file.
- The user begins uploading the wrong video file. Then, part way through the upload, the user specifies the correct video file for upload.
- The user accidentally clicks «Cancel upload» while the video is uploading.
Examples of environmental changes #
- The internet connection goes offline while the video is uploading.
- The browser restarts while the video is uploading.
- The servers for the video-sharing website restart while the video is uploading.
Examples of errors with the video-sharing website #
- The video-sharing website cannot handle a filename with a space. Instead of
"My Travels.mp4"
, it expects a name such as"My_Travels.mp4"
or"MyTravels.mp4"
. - The video-sharing website cannot upload a video that exceeds the maximum acceptable file size.
- The video-sharing website does not support the video codec in the uploaded video.
These examples can and do happen in the real world. You may have encountered such examples in the past! Let’s pick one example from each of the previous categories, and discuss the following points:
- What is the default behavior if the video-sharing service cannot handle the given example?
- What does the user expect to happen in the example?
- How can we improve the process?
Action | The user begins uploading the wrong video file. Then, part way through the upload, the user specifies the correct video file for upload. |
---|---|
What happens by default | The original file continues to upload in the background while the new file uploads at the same time. |
What the user expects | The user expects the original upload to stop so that no extra internet bandwidth is wasted. |
What can be improved | JavaScript cancels the Fetch request for the original file before the new file begins to upload. |
Action | The user loses their internet connection part way through uploading the video. |
---|---|
What happens by default | The upload progress bar appears to be stuck on 50%. Eventually, the Fetch API experiences a timeout and the uploaded data is discarded. When internet connectivity returns, the user has to reupload their file. |
What the user expects | The user expects to be notified when their file cannot be uploaded, and they expect their upload to automatically resume at 50% when they are back online. |
What can be improved | The upload page informs the user of internet connectivity issues, and reassures the user that the upload will resume when internet connectivity has resumed. |
Action | The video-sharing website cannot handle a filename with a space. Instead of «My Travels.mp4», it expects names such as «My_Travels.mp4» or «MyTravels.mp4». |
---|---|
What happens by default | The user must wait for the upload to completely finish. Once the file is uploaded, and the progress bar reads «100%», the progress bar displays the message: «Please try again.» |
What the user expects | The user expects to be told of filename limitations before upload begins, or at least within the first second of uploading. |
What can be improved | Ideally, the video-sharing service supports filenames with spaces. Alternative options are to notify the user of filename limitations before uploading begins. Or, the video-sharing service should reject the upload with a detailed error message. |
Handle errors with the Fetch API #
Note that the following code examples use top-level await
(browser support) because this feature can simplify your code.
When the Fetch API throws errors #
This example uses a try
/catch
block statement to catch any errors thrown within the try
block. For example, if the Fetch API cannot fetch the specified resource, then an error is thrown. Within a catch
block like this, take care to provide a meaningful user experience. If a spinner, a common user interface that represents some sort of progress, is shown to the user, then you could take the following actions within a catch
block:
- Remove the spinner from the page.
- Provide helpful messaging that explains what went wrong, and what options the user can take.
- Based on the available options, present a «Try again» button to the user.
- Behind the scenes, send the details of the error to your error-tracking service, or to the back-end. This action logs the error so it can be diagnosed at a later stage.
try {
const response = await fetch('https://website');
} catch (error) {
// TypeError: Failed to fetch
console.log('There was an error', error);
}
At a later stage, while you diagnose the error that you logged, you can write a test case to catch such an error before your users are aware something is wrong. Depending on the error, the test could be a unit, integration, or acceptance test.
When the network status code represents an error #
This code example makes a request to an HTTP testing service that always responds with the HTTP status code 429 Too Many Requests
. Interestingly, the response does not reach the catch
block. A 404 status, amongst certain other status codes, does return a network error but instead resolves normally.
To check that the HTTP status code was successful, you can use any of the following options:
- Use the
Response.ok
property to determine whether the status code was in the range from200
to299
. - Use the
Response.status
property to determine whether the response was successful. - Use any other metadata, such as
Response.headers
, to assess whether the response was successful.
let response;try {
response = await fetch('https://httpbin.org/status/429');
} catch (error) {
console.log('There was an error', error);
}
// Uses the 'optional chaining' operator
if (response?.ok) {
console.log('Use the response here!');
} else {
console.log(`HTTP Response Code: ${response?.status}`)
}
The best practice is to work with people in your organization and team to understand potential HTTP response status codes. Backend developers, developer operations, and service engineers can sometimes provide unique insight into possible edge cases that you might not anticipate.
When there is an error parsing the network response #
This code example demonstrates another type of error that can arise with parsing a response body. The Response
interface offers convenient methods to parse different types of data, such as text or JSON. In the following code, a network request is made to an HTTP testing service that returns an HTML string as the response body. However, an attempt is made to parse the response body as JSON, throwing an error.
let json;try {
const response = await fetch('https://httpbin.org/html');
json = await response.json();
} catch (error) {
if (error instanceof SyntaxError) {
// Unexpected token < in JSON
console.log('There was a SyntaxError', error);
} else {
console.log('There was an error', error);
}
}
if (json) {
console.log('Use the JSON here!', json);
}
You must prepare your code to take in a variety of response formats, and verify that an unexpected response doesn’t break the web page for the user.
Consider the following scenario: You have a remote resource that returns a valid JSON response, and it is parsed successfully with the Response.json()
method. It may happen that the service goes down. Once down, a 500 Internal Server Error
is returned. If appropriate error-handling techniques are not used during the parsing of JSON, this could break the page for the user because an unhandled error is thrown.
When the network request must be canceled before it completes #
This code example uses an AbortController
to cancel an in-flight request. An in-flight request is a network request that has started but has not completed.
The scenarios where you may need to cancel an in-flight request can vary, but it ultimately depends on your use case and environment. The following code demonstrates how to pass an AbortSignal
to the Fetch API. The AbortSignal
is attached to an AbortController
, and the AbortController
includes an abort()
method, which signifies to the browser that the network request should be canceled.
const controller = new AbortController();
const signal = controller.signal;// Cancel the fetch request in 500ms
setTimeout(() => controller.abort(), 500);
try {
const url = 'https://httpbin.org/delay/1';
const response = await fetch(url, { signal });
console.log(response);
} catch (error) {
// DOMException: The user aborted a request.
console.log('Error: ', error)
}
Conclusion #
One important aspect of handling errors is to define the various parts that can go wrong. For each scenario, make sure you have an appropriate fallback in place for the user. With regards to a fetch request, ask yourself questions such as:
- What happens if the target server goes down?
- What happens if Fetch receives an unexpected response?
- What happens if the user’s internet connection fails?
Depending on the complexity of your web page, you can also sketch out a flowchart which describes the functionality and user interface for different scenarios.
Return to all articles