FileSaver-eligrey

一个允许在客户端保存文件的解决方案

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/450828/1090308/FileSaver-eligrey.js

  1. function enableSaveAs() {
  2.  
  3. /*
  4. * FileSaver.js
  5. * A saveAs() FileSaver implementation.
  6. *
  7. * By Eli Grey, http://eligrey.com
  8. *
  9. * License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)
  10. * source : http://purl.eligrey.com/github/FileSaver.js
  11. */
  12.  
  13. // The one and only way of getting global scope in all environments
  14. // https://stackoverflow.com/q/3277182/1008999
  15. var _global = typeof window === 'object' && window.window === window
  16. ? window : typeof self === 'object' && self.self === self
  17. ? self : typeof global === 'object' && global.global === global
  18. ? global
  19. : this
  20.  
  21. function bom(blob, opts) {
  22. if (typeof opts === 'undefined') opts = { autoBom: false }
  23. else if (typeof opts !== 'object') {
  24. console.warn('Deprecated: Expected third argument to be a object')
  25. opts = { autoBom: !opts }
  26. }
  27.  
  28. // prepend BOM for UTF-8 XML and text/* types (including HTML)
  29. // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
  30. if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
  31. return new Blob([String.fromCharCode(0xFEFF), blob], { type: blob.type })
  32. }
  33. return blob
  34. }
  35.  
  36. function download(url, name, opts) {
  37. var xhr = new XMLHttpRequest()
  38. xhr.open('GET', url)
  39. xhr.responseType = 'blob'
  40. xhr.onload = function () {
  41. saveAs(xhr.response, name, opts)
  42. }
  43. xhr.onerror = function () {
  44. console.error('could not download file')
  45. }
  46. xhr.send()
  47. }
  48.  
  49. function corsEnabled(url) {
  50. var xhr = new XMLHttpRequest()
  51. // use sync to avoid popup blocker
  52. xhr.open('HEAD', url, false)
  53. try {
  54. xhr.send()
  55. } catch (e) { }
  56. return xhr.status >= 200 && xhr.status <= 299
  57. }
  58.  
  59. // `a.click()` doesn't work for all browsers (#465)
  60. function click(node) {
  61. try {
  62. node.dispatchEvent(new MouseEvent('click'))
  63. } catch (e) {
  64. var evt = document.createEvent('MouseEvents')
  65. evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80,
  66. 20, false, false, false, false, 0, null)
  67. node.dispatchEvent(evt)
  68. }
  69. }
  70.  
  71. // Detect WebView inside a native macOS app by ruling out all browsers
  72. // We just need to check for 'Safari' because all other browsers (besides Firefox) include that too
  73. // https://www.whatismybrowser.com/guides/the-latest-user-agent/macos
  74. var isMacOSWebView = _global.navigator && /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent)
  75.  
  76. var saveAs = _global.saveAs || (
  77. // probably in some web worker
  78. (typeof window !== 'object' || window !== _global)
  79. ? function saveAs() { /* noop */ }
  80.  
  81. // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView
  82. : ('download' in HTMLAnchorElement.prototype && !isMacOSWebView)
  83. ? function saveAs(blob, name, opts) {
  84. var URL = _global.URL || _global.webkitURL
  85. // Namespace is used to prevent conflict w/ Chrome Poper Blocker extension (Issue #561)
  86. var a = document.createElementNS('http://www.w3.org/1999/xhtml', 'a')
  87. name = name || blob.name || 'download'
  88.  
  89. a.download = name
  90. a.rel = 'noopener' // tabnabbing
  91.  
  92. // TODO: detect chrome extensions & packaged apps
  93. // a.target = '_blank'
  94.  
  95. if (typeof blob === 'string') {
  96. // Support regular links
  97. a.href = blob
  98. if (a.origin !== location.origin) {
  99. corsEnabled(a.href)
  100. ? download(blob, name, opts)
  101. : click(a, a.target = '_blank')
  102. } else {
  103. click(a)
  104. }
  105. } else {
  106. // Support blobs
  107. a.href = URL.createObjectURL(blob)
  108. setTimeout(function () { URL.revokeObjectURL(a.href) }, 4E4) // 40s
  109. setTimeout(function () { click(a) }, 0)
  110. }
  111. }
  112.  
  113. // Use msSaveOrOpenBlob as a second approach
  114. : 'msSaveOrOpenBlob' in navigator
  115. ? function saveAs(blob, name, opts) {
  116. name = name || blob.name || 'download'
  117.  
  118. if (typeof blob === 'string') {
  119. if (corsEnabled(blob)) {
  120. download(blob, name, opts)
  121. } else {
  122. var a = document.createElement('a')
  123. a.href = blob
  124. a.target = '_blank'
  125. setTimeout(function () { click(a) })
  126. }
  127. } else {
  128. navigator.msSaveOrOpenBlob(bom(blob, opts), name)
  129. }
  130. }
  131.  
  132. // Fallback to using FileReader and a popup
  133. : function saveAs(blob, name, opts, popup) {
  134. // Open a popup immediately do go around popup blocker
  135. // Mostly only available on user interaction and the fileReader is async so...
  136. popup = popup || open('', '_blank')
  137. if (popup) {
  138. popup.document.title =
  139. popup.document.body.innerText = 'downloading...'
  140. }
  141.  
  142. if (typeof blob === 'string') return download(blob, name, opts)
  143.  
  144. var force = blob.type === 'application/octet-stream'
  145. var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari
  146. var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent)
  147.  
  148. if ((isChromeIOS || (force && isSafari) || isMacOSWebView) && typeof FileReader !== 'undefined') {
  149. // Safari doesn't allow downloading of blob URLs
  150. var reader = new FileReader()
  151. reader.onloadend = function () {
  152. var url = reader.result
  153. url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;')
  154. if (popup) popup.location.href = url
  155. else location = url
  156. popup = null // reverse-tabnabbing #460
  157. }
  158. reader.readAsDataURL(blob)
  159. } else {
  160. var URL = _global.URL || _global.webkitURL
  161. var url = URL.createObjectURL(blob)
  162. if (popup) popup.location = url
  163. else location.href = url
  164. popup = null // reverse-tabnabbing #460
  165. setTimeout(function () { URL.revokeObjectURL(url) }, 4E4) // 40s
  166. }
  167. }
  168. )
  169.  
  170. _global.saveAs = saveAs.saveAs = saveAs
  171.  
  172. if (typeof module !== 'undefined') {
  173. module.exports = saveAs;
  174. }
  175. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址