Я пытаюсь получить списки пользователей GET с сервера node.js с помощью API-интерфейса выборки, используя POST-код json {pageNumber,UsersPerPage}. Для этого у меня есть две кнопки, каждая из которых отправляет на сервер свое собственное текстовое содержимое в виде номеров страниц при нажатии. Однако после шестикратного повторения двух кнопок API выборки почему-то не работает. Это не удается после того, как я отправляю 6 запросов на выборку - поэтому, когда я шесть раз перебираю между двумя кнопками - и появляется сообщение об ошибке «Необнаруженный (в обещании) TypeError: Не удалось получить данные в HTMLDivElement». возвращается.
Это мой код интерфейса:
side1.addEventListener('click',()=>{
fetch('/api/users/stats/side1/post',{
method:'POST',
headers:{'Content-Type':'application/json'},
body:JSON.stringify({
pageNum:side1.textContent,
userPerPage:userPerSide
})
});
fetch('/api/users/stats/side1/get').then(x=>x.text()).then(Txt=>{
display.innerHTML=Txt;
});
});
side2.addEventListener('click', ()=>{
fetch('/api/users/stats/side2/post',{
method:'POST' ,
headers:{'Content-Type':'application/json'},
body:JSON.stringify({
pageNum:side2.textContent,
userPerPage:userPerSide
})
});
fetch('/api/users/stats/side2/get').then(x=>x.text()).then(Txt=>{
display.innerHTML=Txt;
});
});
Это мой бэкэнд — код:
var retVal;
app.post('/api/users/stats/side1/post',(req,res)=>{
if (req.body){
const {pageNum,userPerPage}=req.body;
retVal=GetPage(Number(pageNum),Number(userPerPage));
}
});
app.post('/api/users/stats/side2/post',(req,res)=>{
if (req.body){
const {pageNum,userPerPage}=req.body;
retVal=GetPage(Number(pageNum),Number(userPerPage));
}
});
app.get('/api/users/stats/side1/get',(req,res)=>{
res.setHeader('content-type', 'text/plain');
res.send(retVal);
});
app.get('/api/users/stats/side2/get',(req,res)=>{
res.setHeader('content-type', 'text/plain');
res.send(retVal);
});
Я пробовал разные флаги заголовков, например явное объявление Access-Control-Allow-Origin или no-cors, а также async, await во внешнем интерфейсе. Ошибка возникает независимо от типа контента, возвращаемого сервером. Я попытался упростить код и изменить URL-адреса POST и GET для разных объектов html, чтобы избежать коллизий. Я ожидал, что запросы на выборку будут выполнены без какой-либо блокировки. Я уже выполнял поиск в Интернете, а также в stackoverflow, и хотя другие вопросы кажутся мне знакомыми, я думаю, они касаются совершенно другой проблемы.
Что я выучил: Проблема не возникает из-за того, что запросы занимают слишком много времени. И это не из-за того, что Javascript не может взаимодействовать с моим сервером, поскольку первые 5 запросов работают как положено, а затем код ломается. Глядя на вкладку сети, запросы внезапно становятся ожидающими, поэтому после этого момента они перестают проходить.
Проблема возникает не здесь, а где-то в логике получения/отправки, я просто не могу понять, где. Однако спасибо за вклад. Возможно, я отредактирую сообщение, чтобы было видно, что проблема не в этом.
Вы проверяли вкладку «Сеть» в инструментах разработчика? Чтобы увидеть, в чем ошибка запроса?
Что также интересно, так это то, что ему не удалось получить HTMl_Div_Element, это относится к вызову выборки, который отправляет POSTSside1.textContent, но как он вдруг не получает это?? Страница также не может перезагрузиться на этом этапе. Так происходит ли еще какая-то блокировка и как?
Да, я проверил вкладку «Сеть». Что происходит с запросами, так это то, что они находятся на рассмотрении. Итак, они каким-то образом перестают проходить, поэтому, вероятно, происходит какая-то блокировка, но я просто не могу понять, где это будет.
Ну, это очень странный код. Ваше сообщение предварительно заполняет ответ get. Почему POST просто не возвращает ответ? Вам не придется делать два звонка. Кроме того, ваша выборка GET не ожидает завершения POST, поэтому retVal может находиться в другом состоянии, чем вы ожидаете. Кроме того, если на этом сервере есть два пользователя, они смогут связываться с возвращаемыми значениями друг друга.
Если вызов остается ожидающим, это может означать, что на сервере произошла ошибка и клиент не получил ответа... Я думаю, что GetPage медленно обрабатывает или создает ошибку? Вы можете проверить журналы сервера и посмотреть, есть ли что-то необычное.
В дополнение к тому, что @Salketer правильно указал, что эта идея неверна, отсутствие обработки ошибок является #проблемным. В зависимости от версии node.js один неверный запрос может привести к сбою всего вашего сервера....
Ошибка возникает, даже если ответ будет постоянной строкой. Так что дело не в том, насколько быстр GetPage.
Не могли бы вы уточнить, как вы будете ждать ответа на запрос GET?
@BellFlo, чтобы внести ясность: у вас куча проблем с вашим кодом. Не стоит беспокоиться о проблеме, о которой вы спрашиваете, пока вы ее не устраните, потому что они могут быть причиной вашей проблемы, а могут и не быть. Используйте правильное управление состоянием, правильную обработку ошибок, правильную цепочку асинхронных задач, а если это по-прежнему не работает, вернитесь и обновите вопрос/задайте новый вопрос.
await fetch(post); await fetch(get); Ключевое слово await будет ждать разрешения промисов, прежде чем продолжить, а fetch возвращает промис. Кстати, как говорится, действительно странно публиковать данные и получать статус в другом вызове. Если сообщение изменяет что-то, что должно возвращать статус, сам запрос на публикацию должен возвращать статус, поэтому он будет атомарным во внешнем интерфейсе (и во внутреннем интерфейсе это должно быть сделано правильно и тоже быть атомарным. Вы должны прочитать о «атомарность», потому что у вас здесь куча проблем, поверьте мне, вам будет полезно узнать об атомарности в мире программирования).
Я благодарю всех за ответы, проблема заключалась в том, что я не знал, что можно связать получение и получение сообщения вместе, и это вызвало все остальные проблемы, а также причину моего запутанного серверного интерфейса. Я новичок в node.js - как, вероятно, показал вам код - и я благодарю всех за усилия, а также за стандарты stackoverflow - чрезвычайно приятные и полезные вопросы.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Во-первых, я думаю, вы могли бы сократить ваши 4 звонка до одного.
app.post('/api/users/stats/post',(req,res)=>{
if (req.body){
const {pageNum,userPerPage}=req.body;
res.send(GetPage(Number(pageNum),Number(userPerPage)));
}else{
// Missing body, say that the input is bad.
res.sendStatus(422);
}
});
Одного этого достаточно.
Я удалил часть «side1», поскольку код точно такой же, как для стороны2. Итак, давайте сохраним только один маршрут и удалим эту побочную вещь.
Затем, поскольку POST использовался для «предварительной настройки» результата следующего GET, GET совершенно излишен, поскольку POST может просто вернуть результат напрямую. Устранение необходимости целого путешествия туда и обратно. В то же время это полностью устраняет проблему необходимости вызывать post перед get и гарантировать, что никто больше не вызовет post, пока я не вызову get.
У клиента тоже была пара ошибок. Во-первых, он не ждал завершения вызова POST перед вызовом GET. Поэтому вполне возможно, что GET получит предыдущее значение вместо правильного. Но мы исправили это, используя только одну конечную точку POST.
side1.addEventListener('click',()=>{
fetch('/api/users/stats/post',{
method:'POST',
headers:{'Content-Type':'application/json'},
body:JSON.stringify({
pageNum:side1.textContent,
userPerPage:userPerSide
})
}).then(x=>x.text()).then(Txt=>{
display.innerHTML=Txt;
});
});
side2.addEventListener('click',()=>{
fetch('/api/users/stats/post',{
method:'POST',
headers:{'Content-Type':'application/json'},
body:JSON.stringify({
pageNum:side2.textContent,
userPerPage:userPerSide
})
}).then(x=>x.text()).then(Txt=>{
display.innerHTML=Txt;
});
});
Теперь это снова становится немного менее сложным.
Есть и другая очистка кода, которую мы могли бы сделать, например, использование одного и того же прослушивателя событий для обоих объектов и т. д., но я пока оставляю это, чтобы прояснить ответ.
Чтобы внести ясность: это не решает проблему ОП. Но с кодом было много странных/неправильных вещей, и очистки, скорее всего, будет достаточно, чтобы исправить это естественным путем.
хорошо, значит, вы можете дождаться вызова get, связав выборку GET непосредственно с выборкой POST?
Чтобы уточнить, я использовал операторы GET и POST, потому что серверная часть жаловалась каждый раз, когда я просто использовал POST, так что, похоже, проблема заключалась в том, что у меня тогда было два отдельных оператора во внешней части?
Проблема с кодом заключалась в том, что у меня было два отдельных оператора выборки во внешнем интерфейсе.
fetch(post);
fetch(get);
Это заставило меня использовать два разных вызова метода на бэкэнде. Я узнал, что для получения ответа на запрос от сервера вам НЕОБХОДИМО использовать:
fetch(post).then(...);
Поскольку это говорит javascript дождаться завершения первой функции. Итак, мой главный недостаток в понимании заключался в том, что:
funcA().funcB(); -> synchronous
funcA();funcB(); -> asynchronous
Возможно, проблема в том, что вы не передаете заголовки
Content-TypeиContent-Lengthперед вызовомres.send(retVal).