【问题标题】:aborting multiple xhr requests中止多个 xhr 请求
【发布时间】:2016-12-03 14:34:08
【问题描述】:

考虑这种情况:我有一个项目列表和分页来按块加载它们。在每个下一页单击新的 XHR 调用以获取新的项目部分。当用户点击得非常快时,我有很多 xhrs 实际上没有必要,因为用户只想要最后点击的页面项目并且他们也占用资源。所以我可以中止除最后一个未决请求之外的所有请求,为它们中的每一个调用 xhr.abort()。问题是:中止多个 xhr 是否安全?我读到服务器可能认为这是某种攻击。如果是这样,要与后端人员检查哪些设置?

注意:产生 xhrs 的函数已经去抖动了 400 毫秒。

【问题讨论】:

  • 我个人会采取在当前有活动请求时忽略点击的方法,类似于在点击提交按钮时禁用提交按钮的过程。
  • 或者如果你检测到一个新的请求就取消请求,或者取消调用,这样就不能快速进行多个。
  • 点击时发生的功能被去抖,但我们的测试人员仍然设法每 200 毫秒同时点击一次,一旦去抖时间更改为 400 毫秒 - 每 410 毫秒一次,等等。仍然有很多请求
  • 所以在返回最后一个之前不要打电话?
  • 也许将请求保存在数组中,或者保存到带有时间戳的对象中,以便选择特定请求。就我个人而言,我只是在任何执行 xhr 的路由器调用中中止所有待处理的 xhr 请求,而且我还没有遇到任何问题。

标签: javascript security xmlhttprequest


【解决方案1】:

与其取消一个挂起的 xhr 请求,不如在发送请求之前将事件 debuff 几百毫秒。每次点击按钮时,您都会重置一个延迟 xhr 请求的计时器

const button = document.querySelector('#button')
const url = 'https://jsonplaceholder.typicode.com/posts/1'

const request = (function() {
  // save the current ajax request in the closure
  let ajax = null
  return function(url, params, cb) {
    if (ajax) {
      // if there is a current request cancel it
      ajax.abort()
      console.log('aborted ajax request')
    }
    // set a new xhr
    ajax = new XMLHttpRequest
    ajax.onreadystatechange = function() {
      if (ajax.readyState === 4 && ajax.status === 200) {
        // run the callback with the response
        cb(JSON.parse(ajax.responseText))
        // remove the previous request
        ajax = null
      }
    }
    ajax.open('GET', url, true)
    ajax.send(params)
  }
})()

const clickCallback = debuff(function(e) {
  console.log('clicked')
  // make the xhr request
  request(url, null, function(response) {
    console.log('response', response)
  })
}, 100)
                             
button.addEventListener('click', clickCallback, false)

function debuff(fn, delay) {
  let timer = null
  return function(e) {
    clearTimeout(timer)
    timer = setTimeout(e => fn(e), delay || 250, e)
  }
}
<button id="button">debuffed click</button>

【讨论】:

  • 谢谢,但正如我在 cmets 中写的那样,它已经实现了,我仍然有需要中止请求的情况
  • @OlenaHoral 好的,抱歉我没看到。
  • @OlenaHoral 我已经更新了我的答案。这会将当前的 ajax 请求保存到 request 闭包中,如果有任何未决的请求,则会取消任何先前的请求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多