首页 文章

Javascript和HTML5文件API - 将文件正确路由到函数的问题

提问于
浏览
0

我想知道如何为HTML5 'file'对象定义文件引用,以用作JavaScript函数的输入,该函数将文件转换为Base64编码,而不使用交互式文件输入元素 . 我已经看过HTML5Rocks示例和其他许多示例,但它们都使用 <input type=file> 元素来读取和收集有关要操作的文件的输入 . 我打算将图像文件(即二进制)作为输入,并输出Base64字符串 . (也许很明显,但我是HTML5和JavaScript世界的新手)

我的一些阅读似乎表明出于安全原因这是不可能的:JS然后可以运行任意文件 . 我想仔细检查一下 .

“文件”输入类型的输出是什么?我可以用某种方式手动模仿它吗? (我在这里找到一个关于直接在JS中包含文件本身的引用,但是你能用二进制文件吗?坦率地说,不知道我在FileMaker方面会怎么做,不过 . 我的计划,直到这一点,是将文件从FileMaker导出到已知位置,然后使用该位置作为JavaScript的输入)

整体情况:我正在尝试在FileMaker 12中创建一个自包含的web-viewer元素 . 在FileMaker中,我可以在运行它之前动态定义我的HTML和JavaScript . 我想动态硬编码JavaScript到ALREADY包含基于数据库信息的文件引用(即路径和文件名) . 这都在本地计算机上运行,不涉及任何服务器 .

我试图最小化最终用户为了获得文件编码而必须进行的交互:我不希望他们必须将图像放入数据库,然后还必须再次删除(或文件选择)图像在Web查看器中 . 我想将所有这些代码保存在FileMaker数据库中,使其更加便携和健壮,即不必依赖互联网连接 . 因此,用户将其文件放入数据库,数据库自动检测该事件,计算JavaScript(包括文件的路径),JavaScript在其上运行Base64函数,将编码的字符串返回到数据库 .

也许我应该反过来做:让用户将文件放入JavaScript区域,然后将其复制到数据库中 . 但是,不确定JavaScript是否有任何与数据库交互的句柄 .

------------------------编辑(除了原始问题的一些标记和标记)

我们现在暂时忽略整个FileMaker方面 . 我决定采用HTML5和JavaScript作为文件输入部分的路线(而不是尝试在FM中读取它然后输出到JS) . 只是为了看看我是否可以让JavaScript部分工作 .

这是我正在玩的一些代码 . 它主要来自HTML5 Rocks演示,以及我发现的base64编码例程 . 但是,我遇到的问题是如何定义和调用我的阅读器,onload事件和编码功能 . 任何建议,将不胜感激:

<script>
    //  From:  http://www.html5rocks.com/en/tutorials/file/dndfiles/
    //  JC update:  changing the handleFileSelect() function to do the base64 Processing

  function base64Encode(aFile) {
      /*
       * base64.js - Base64 encoding and decoding functions
       * See: http://developer.mozilla.org/en/docs/DOM:window.btoa
       *      http://developer.mozilla.org/en/docs/DOM:window.atob
       * Copyright (c) 2007, David Lindquist <david.lindquist@gmail.com>
       * Released under the MIT license
       *
       * JC, update:  Removed the 'atob' section of code; only need ENcoding, not DEcoding.
       */

      if (typeof btoa == 'undefined') {
          function btoa(str) {
              var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
              var encoded = [];
              var c = 0;
              while (c < str.length) {
                  var b0 = str.charCodeAt(c++);
                  var b1 = str.charCodeAt(c++);
                  var b2 = str.charCodeAt(c++);
                  var buf = (b0 << 16) + ((b1 || 0) << 8) + (b2 || 0);
                  var i0 = (buf & (63 << 18)) >> 18;
                  var i1 = (buf & (63 << 12)) >> 12;
                  var i2 = isNaN(b1) ? 64 : (buf & (63 << 6)) >> 6;
                  var i3 = isNaN(b2) ? 64 : (buf & 63);
                  encoded[encoded.length] = chars.charAt(i0);
                  encoded[encoded.length] = chars.charAt(i1);
                  encoded[encoded.length] = chars.charAt(i2);
                  encoded[encoded.length] = chars.charAt(i3);
              }
              return encoded.join('');
          }
      }
  }

  function handleFileSelect(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    var files = evt.dataTransfer.files; // FileList object - a FileList of File objects.
    var fReader = new FileReader () ;  
    var output = [];
    for (var i = 0, f; f = files[i]; i++) {
      if ( !f.type.match('image.*')) { continue; }    //To skip non-image files
      fReader.onLoad = (function (aFile) { return base64Encode(aFile); } ) (f);
      output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
                  f.size, ' bytes, last modified: ',
                  f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
                  '<br><br>' , fReader.readAsBinaryString(f) , '<br><br>', '</li>');
     //This defines the 'onLoad' behavior/function...I think.

    }
    document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
  }

  function handleDragOver(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
  }

  // Setup the dnd listeners.  [Slightly modified by JC]
  var dropZone = document.getElementById('drop_zone');
  dropZone.addEventListener('dragover', handleDragOver, false);
  dropZone.addEventListener('drop', handleFileSelect, false);
</script>

1 回答

  • 0

    不,在Web浏览器中,您无法访问用户计算机上的任意文件 . 永远不能 .

    您可以从网络中获取文件(但只有来自同一来源或通过CORS允许才读取内容,并且 file:// 协议不会使用沙盒文件系统(不是用户自己放在那里) .

    你可以自己创建“文件”:

    var file = new Blob(["file content"], {type:"text/plain"})
    

    BlobFile 的基类,它通常可用于 input.files[] 所在的任何地方 .

    您可能有权访问其他基于JS的环境(如窗口小部件或浏览器扩展)中的本地文件 .

相关问题