js 写入文件存到本地,可用于抓取接口数据

  工作中有时需要通过 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

posted @ 2019-06-19 11:13  潇影D  阅读(10665)  评论(0编辑  收藏  举报