【问题标题】:Fetch request makes unwanted page reload获取请求会导致不需要的页面重新加载
【发布时间】:2023-03-27 22:53:01
【问题描述】:

我遇到了从客户端到服务器的获取请求的问题。 不知何故,获取请求导致页面重新加载,这是我想避免的。我已经搜索了几个地方才能弄清楚这一点,但我必须向你们寻求帮助。

数据库之间的所有数据事务都按预期工作。显然功能中没有错误。除了我不希望页面在触发获取请求时重新加载。

请注意,我使用 EJS 作为模板引擎,使用 Bootstrap 4 作为前端库。

请看我下面的代码。非常感谢任何避免页面重新加载的提示。

前端 HTML:

// detailjs.ejs

<div class="row">
    <form>
        <button class="btn btn-outline-primary" onclick="UpdateArchiveStatus(this)" id="btn-move-to-inbox"><i class="fas fa-inbox"></i> Flytt til innboks</button>
        <button class="btn btn-outline-primary" onclick="UpdateArchiveStatus(this)" id="btn-move-to-archive"><i class="fas fa-archive"></i> Arkiver</button>
    </form>
</div>

<div class="row">
    <input type="hidden" name="resolved-status" id="resolved-status" value="<%= message.status.isResolved %>">
    <input type="hidden" name="archive-status" id="archive-status" value="<%= message.status.isArchived %>">
</div>

<!-- Script include --!>
<script src="/assets/js/messages/message-admin.js">

前端 JavaScript

//message-admin.js

const UpdateArchiveStatus = btn => {
var messageId = $('#message-id').val();
var currentArchiveStatus = $('#archive-status').val();
var newArchiveStatus = null;

if (currentArchiveStatus == 'true') {
    newArchiveStatus = false;
 } else {
   newArchiveStatus = true;
 }
 StoreArchiveStatus(messageId, newArchiveStatus);
};

function StoreArchiveStatus (messageId, archiveStatus) {
    fetch(`/backoffice/api/messages/archive/${messageId}/${archiveStatus}`, 
    {
        method: 'GET',
    })
    .then(result => {
         return result.json();
    })
    .then(data => {
        $('#archive-status').val(data.status);
        CheckArchiveStatus();
        console.log(data.message);
    })
    .catch(err => {
        console.log(err);
     });
    };

function ToggleArchivedInterface () {
    var inboxButton   = $('#btn-move-to-inbox');
    var archiveButton = $('#btn-move-to-archive');

    inboxButton.removeClass('invisible');
    archiveButton.addClass('invisible');
};

function ToggleInboxInterface () {
    var inboxButton   = $('#btn-move-to-inbox');
    var archiveButton = $('#btn-move-to-archive');

    archiveButton.removeClass('invisible');
    inboxButton.addClass('invisible');
};

async function CheckArchiveStatus () {
    var archiveStatus = $('#archive-status').val();
    if (archiveStatus == 'true') {
        ToggleArchivedInterface();
    } else {
        ToggleInboxInterface();
    }
};

后端路由:

//routes/backoffice.js

router.get('/api/messages/archive/:messageId/:archiveStatus', authenticate, backofficeController.apiUpdateMessageArchiveStatus);

后端控制器功能:

//controllers/backoffice.js

exports.apiUpdateMessageResolvedStatus = (req, res, next) => {
    var messageId      = req.params.messageId;
    var resolvedStatus = req.params.resolvedStatus;

    VisitorMessage.findOneAndUpdate(
        { '_id' : messageId },
        { $set: {
            'status.isResolved': resolvedStatus
        }
    }).then((message) => {
        res.status(200).json({message: `Message status was changed`, status: resolvedStatus})
   }).catch((err) => {
       console.log('The following error occured during update:\n' + err);
       res.status(500).json({message: 'An error occured during update.'});
   })
};

【问题讨论】:

  • 获取请求不会导致页面重新加载。
  • 是的,很确定,因为按钮在表单中,它默认为提交。

标签: javascript node.js ajax rest express


【解决方案1】:

问题是,当您单击按钮时,表单正在提交并导致页面重新加载。

你可以看到问题在行动here

function btnclick(e) {
  // comment and uncomment e.preventDefault to see the differences
  e.preventDefault()
}

阻止默认事件动作,问题就解决了。

【讨论】:

  • 谢谢你,米歇尔。我将您的答案标记为解决方案。这与其他建议的方法有点不同,但也起到了作用。
  • 天啊,为什么这被否决了?完全正确。
  • 我也遇到过同样的问题,与其阻止默认设置,不如建议您重新评估您是否需要表单。在我的情况下,我只是用 div 替换了表单。
【解决方案2】:

正如 SpeedOfRound 评论的那样,他是完全正确的。我自己没有看到这个问题。感谢您的帮助!

解决方案: 删除detailjs.ejs 文件中多余的&lt;form&gt; 标记。即使我使用的是获取请求,这些标签也会导致页面自行刷新。

【讨论】:

    猜你喜欢
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    • 2021-05-15
    • 1970-01-01
    • 1970-01-01
    • 2020-01-13
    相关资源
    最近更新 更多