handsome-jm

  工作中有时需要通过 JavaScript 保存文件到本地,我们都知道 JavaScript 基于安全的考虑,是不允许直接操作本地文件的。
IE 可以通过 VB 插件的方式进行,而 Chrome 和 firefox 都不支持 JavaScript 向本地写入文件,所以 VB 插件的方式存在兼容性问题。
那有没有适合的方法呢?答案是肯定的,我们可以通过 FileSaver.js 这个小插件实现我们的需求。下面看一段具体的代码吧:

 

  // 此处案例用来抓取阿里地图数据
  function demo() {
    var id = \'100000\'
    var num = 0
    var time = 0 // 如果使用for循环,文件过多,可能会丢失文件,故使用延迟
    function bound(id) {
      setTimeout(() => {
        $.ajax({
          url: \'https://datavmap-public.oss-cn-hangzhou.aliyuncs.com/areas/bound/\' + id + \'.json\',
          success(res) {
            // num++
            // console.log(num)
            // downloadTextFile(id, JSON.stringify(res))
          }
        })
      }, time)
      time += 200
    }
    function children(id) {
      $.ajax({
        url: \'https://datavmap-public.oss-cn-hangzhou.aliyuncs.com/areas/children/\' + id + \'.json\',
        success(res) {
          // num++
          // console.log(num)
          bound(id)
          // downloadTextFile(id, JSON.stringify(res))
          if (res.features.length) {
            for (let i = 0; i < res.features.length; i++) {
              const adcode = res.features[i].properties.adcode
              if (!res.features[i].properties.childrenNum) { // 如果没有子集数据
                bound(adcode)
                continue
              }
              if (adcode != id) {
                children(adcode)
              }
            }
          }
        }
      })
    }
    children(id)
  }
  demo()
  /**
   * 下载文件
   * name 文件名
   * mobileCode 文件内容
   */
  var downloadTextFile = function (name, mobileCode) {
    if (!mobileCode) {
      mobileCode = \'\'
    }
    // 采用的字符编码格式为“UTF-8”,这样就避免的中文乱码的问题。
    var file = new File([mobileCode], name + ".json", { type: "text/plain;charset=utf-8" })
    saveAs(file)
  }

  

附 FileSaver.js 文件的完整源码:

 

/* FileSaver.js
 * A saveAs() FileSaver implementation.
 * 1.3.2
 * 2016-06-16 18:25:19
 *
 * By Eli Grey, http://eligrey.com
 * License: MIT
 *   See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
 */

/* global self */
/* jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */

/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */

var saveAs = saveAs || (function (view) {
  \'use strict\'
  // IE <10 is explicitly unsupported
  if (typeof view === \'undefined\' || typeof navigator !== \'undefined\' && /MSIE [1-9]\./.test(navigator.userAgent)) {
    return
  }
  var
    doc = view.document
  // only get URL when necessary in case Blob.js hasn\'t overridden it yet
  var get_URL = function () {
    return view.URL || view.webkitURL || view
  }
  var save_link = doc.createElementNS(\'http://www.w3.org/1999/xhtml\', \'a\')
  var can_use_save_link = \'download\' in save_link
  var click = function (node) {
    var event = new MouseEvent(\'click\')
    node.dispatchEvent(event)
  }
  var is_safari = /constructor/i.test(view.HTMLElement) || view.safari
  var is_chrome_ios = /CriOS\/[\d]+/.test(navigator.userAgent)
  var throw_outside = function (ex) {
    (view.setImmediate || view.setTimeout)(function () {
      throw ex
    }, 0)
  }
  var force_saveable_type = \'application/octet-stream\'
  // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
  var arbitrary_revoke_timeout = 1000 * 40 // in ms
  var revoke = function (file) {
    var revoker = function () {
      if (typeof file === \'string\') { // file is an object URL
        get_URL().revokeObjectURL(file)
      } else { // file is a File
        file.remove()
      }
    }
    setTimeout(revoker, arbitrary_revoke_timeout)
  }
  var dispatch = function (filesaver, event_types, event) {
    event_types = [].concat(event_types)
    var i = event_types.length
    while (i--) {
      var listener = filesaver[\'on\' + event_types[i]]
      if (typeof listener === \'function\') {
        try {
          listener.call(filesaver, event || filesaver)
        } catch (ex) {
          throw_outside(ex)
        }
      }
    }
  }
  var auto_bom = function (blob) {
    // prepend BOM for UTF-8 XML and text/* types (including HTML)
    // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
    if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
      return new Blob([String.fromCharCode(0xFEFF), blob], { type: blob.type })
    }
    return blob
  }
  var FileSaver = function (blob, name, no_auto_bom) {
    if (!no_auto_bom) {
      blob = auto_bom(blob)
    }
    // First try a.download, then web filesystem, then object URLs
    var
      filesaver = this
    var type = blob.type
    var force = type === force_saveable_type
    var object_url
    var dispatch_all = function () {
      dispatch(filesaver, \'writestart progress write writeend\'.split(\' \'))
    }
    // on any filesys errors revert to saving with object URLs
    var fs_error = function () {
      if ((is_chrome_ios || (force && is_safari)) && view.FileReader) {
        // Safari doesn\'t allow downloading of blob urls
        var reader = new FileReader()
        reader.onloadend = function () {
          var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, \'data:attachment/file;\')
          var popup = view.open(url, \'_blank\')
          if (!popup) view.location.href = url
          url = undefined // release reference before dispatching
          filesaver.readyState = filesaver.DONE
          dispatch_all()
        }
        reader.readAsDataURL(blob)
        filesaver.readyState = filesaver.INIT
        return
      }
      // don\'t create more object URLs than needed
      if (!object_url) {
        object_url = get_URL().createObjectURL(blob)
      }
      if (force) {
        view.location.href = object_url
      } else {
        var opened = view.open(object_url, \'_blank\')
        if (!opened) {
          // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
          view.location.href = object_url
        }
      }
      filesaver.readyState = filesaver.DONE
      dispatch_all()
      revoke(object_url)
    }

    filesaver.readyState = filesaver.INIT

    if (can_use_save_link) {
      object_url = get_URL().createObjectURL(blob)
      setTimeout(function () {
        save_link.href = object_url
        save_link.download = name
        click(save_link)
        dispatch_all()
        revoke(object_url)
        filesaver.readyState = filesaver.DONE
      })
      return
    }

    fs_error()
  }
  var FS_proto = FileSaver.prototype
  var saveAs = function (blob, name, no_auto_bom) {
    return new FileSaver(blob, name || blob.name || \'download\', no_auto_bom)
  }

  // IE 10+ (native saveAs)
  if (typeof navigator !== \'undefined\' && navigator.msSaveOrOpenBlob) {
    return function (blob, name, no_auto_bom) {
      name = name || blob.name || \'download\'

      if (!no_auto_bom) {
        blob = auto_bom(blob)
      }
      return navigator.msSaveOrOpenBlob(blob, name)
    }
  }

  FS_proto.abort = function () { }
  FS_proto.readyState = FS_proto.INIT = 0
  FS_proto.WRITING = 1
  FS_proto.DONE = 2

  FS_proto.error =
    FS_proto.onwritestart =
    FS_proto.onprogress =
    FS_proto.onwrite =
    FS_proto.onabort =
    FS_proto.onerror =
    FS_proto.onwriteend =
    null

  return saveAs
}(
  typeof self !== \'undefined\' && self ||
  typeof window !== \'undefined\' && window ||
  this.content
))
// `self` is undefined in Firefox for Android content script context
// while `this` is nsIContentFrameMessageManager
// with an attribute `content` that corresponds to the window

if (typeof module !== \'undefined\' && module.exports) {
  module.exports.saveAs = saveAs
} else if ((typeof define !== \'undefined\' && define !== null) && (define.amd !== null)) {
  define(\'FileSaver.js\', function () {
    return saveAs
  })
}

  

摘自:https://www.cnblogs.com/hapday/p/6292957.html

分类:

技术点:

相关文章:

  • 2022-02-03
  • 2021-11-17
  • 2021-12-16
  • 2021-12-14
  • 2021-09-19
  • 2022-02-02
  • 2022-12-23
猜你喜欢
  • 2022-01-14
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-20
相关资源
相似解决方案