利用window.stop+iframe巧妙取消一直在pending的jsonp请求

最近在做一个很奇葩的需求。要需要判断内外网环境。展示不同的页面内容。由于在方案上后端通过ip判断存在某种不可抵抗的因素。无法成功。

所以出了一个替代方案。后端提供一个仅内网可访问的jsonp接口。该接口无任何逻辑,在内网环境下直接返回200.在外网环境下肯定会出现超时.通过超时时间来判断内外网环境。

正常内网可下很正常,但是在外网环境下,由于请求一直在pending.虽然我通过请求超时时间设置500ms,逻辑已处理。但是此时jsonp请求并没有终止。使得页面titile一直在转圈等待。这对用户体验很不友好。而且毕竟我们网站主要是对外的用户。

 

这里为了解决这个问题,核心问题成了如何中止已发出的jsonp请求,在上一篇中提到过,无法使用ajax的abort()方法。

后来同事建议使用window.stop()方法。但是该方法会使得页面所有的请求都会停止。到此感觉自己已经在坑里爬不起来了,准备换方案时。自己灵光一闪。想到一个巧妙的方法。

我通过一个iframe标签单获得一个独立的子window对象。通过iframe引入页面单独发一个jsonp的请求,在发出500ms后,看是否成功,若还在pending,使用window.stop()方法停止请求。

此时停止的只有iframe的子window对象的请求,不会影响父级window正常的请求。

iframe引入的intranet.html代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
<script>
  let _cb2019 = null
  function cb2019 (data) {
    _cb2019 = data
  }
  function setCookie(name, value) {
    document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value) + ";path=/;domain=.jcloud.com";
    document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value) + ";path=/;domain=.jdcloud.com";
  }
  let timer2019 = setTimeout(function(){
    if (_cb2019) {
      // window.parent.postMessage({retCode:200, msg:'iframe success ...'});
      setCookie('jdcloud_intranet_flag', 'Y')
      console.log('iframe success...')
    } else {
      window.stop()
      // window.parent.postMessage({retCode:201, msg:'iframe timeout ...'});
      setCookie('jdcloud_intranet_flag', 'N')
      console.log('iframe timeout...')
    }
    clearTimeout(timer2019)
  },500)
</script>
<script src="//portal-system-test7.jdcloud.com/go/inner/net?callback=cb2019"></script>
</body>
</html>

 

在500ms后判断jsonp返回值是否取到,再通知页面内容。如果intranet.html与当前页面是同一个项目(即iframe的src地址不存在跨越)。可以通过postMessage形式。

window.parent.postMessage({retCode:200, msg:'iframe success ...'});将消息传递给外层window对象
在外层通过window.addEventListener("message", receiveMessage, false);获取通知信息。

由于我修改的部分是多个项目的公共部分。所以存在跨越的问题(二级域名不同。具有相同的一级域名)。所以我采用cookie的形式。

超时请求截图如下:status:canceled

 

posted @ 2019-04-22 15:08  cc_loving  阅读(723)  评论(0编辑  收藏  举报