1

我正在尝试建立一个网页,受信任的用户可以在其中上传本地 CSV 文件,这些文件将由用户解析、验证、审查,然后插入 MySQL 数据库上的各种表中。

该站点的其余部分是使用 PHP 和 jQuery 编写的。我知道如何将 CSV 文件读入 PHP 并生成查询。问题是文件的验证和解析是交互式的——用户需要被询问有关数据的各种信息,将文件中的列与数据库中的字段匹配,并有机会查看和更新​​他们的直到他们确定一切都正确为止。

每次用户更改某些内容时重新加载整个页面似乎有点像 1990 年代,所以我认为 AJAX 将是在客户端执行此操作的方式,但出于“安全原因”,浏览器似乎特别禁止打开本地文件.

我的问题是:

是否有一种普遍接受的模式可以让用户在将文件实际上传到服务器之前根据文件的内容安全有效地做出决定?或者人们真的只是在这种情况下发送几十个 POST 请求?

顺便说一句,我们不使用 Windows 或任何封闭源代码,因此很遗憾该解决方案不能依赖 Internet Explorer 或 ActiveX。

谢谢。

4

4 回答 4

6

如果您使用从 firefox 3.6 和 Chrome 7 开始可用的 javascript FileReader API,则无需向服务器发出任何请求。幸运的是,存在非常有趣的文章,它们非常清楚地解释了 API 的工作原理。

http://www.html5rocks.com/en/tutorials/file/dndfiles/

如果您对不同浏览器中对 API 的支持有疑虑,则会在另一篇文章的末尾显示:

https://developer.mozilla.org/en/DOM/FileReader

我最近使用这个 API 来上传文本和二进制文件,所以如果你决定要尝试它并且有任何疑问,请随时回复我。

于 2012-04-04T22:00:16.903 回答
1

有关如何有效执行此操作的示例,请尝试使用Papa Parse库。

它可以毫无问题地处理非常大的文件。

于 2014-05-20T10:25:53.610 回答
0

您有两大类解决方案:

  • 上传 CSV 并依靠服务器端逻辑来执行转换,并可能与用户交互。这可能包括加载一个浏览器页面,该页面在上传后实现第二个选择。
  • 让用户将文件复制并粘贴到浏览器文本框中,并使用基于浏览器的 javascript 或小程序来转换文本,可能在本地或与网络服务器交互。

两者都可以通过基于标准的实现来完成。最不寻常的选择是依赖于用户复制/粘贴的第二选择。出于这个原因,大多数实现会选择第一个选项的一些变体。

文件转换的主要逻辑放在哪里取决于你。如果小心的话,这不会有任何安全问题。

于 2012-04-04T21:50:18.877 回答
0

HTML:

<form id = "emailform" action = "admincsvupload" role="form" method="post" enctype="multipart/form-data">
<div class="form-group">
<label class="sr-only" for="csvfile">Upload CSV</label>
<input type="file" name = "csvfile" class="form-control" id="csvfile" placeholder="Select CSV file">                 
</div>
<button type="button" class="btn btn-success" id="btnLoad">Load</button>
<button type="submit" class="btn btn-success" id="btnSubmit" style="display:none">Upload Now!</button>
</form>

0%

Javascript:

  // File load as HTMl n a table before actuly upload it on the server



    function updateProgress(evt) {
    // evt is an ProgressEvent.
    if (evt.lengthComputable) {
        var percentLoaded = Math.round((evt.loaded / evt.total) * 100);
        // Increase the progress bar length.
        if (percentLoaded < 100) {
            progress.style.width = percentLoaded + '%';
            progress.textContent = percentLoaded + '%';
        }
    }
}

     function readBlob(opt_startByte, opt_stopByte) {
    var progress = document.querySelector('.percent');
    var files = document.getElementById('csvfile').files;
    if (!files.length) {
        alert('Please select a file!');
        return;
    }

    var file = files[0];
    var start = 0;
    var stop = file.size - 1;
    progress.style.width = '0%';
    progress.textContent = '0%';
    var reader = new FileReader();

    //Reader progress 
    reader.onprogress = updateProgress;

    // If we use onloadend, we need to check the readyState.
    reader.onloadend = function (evt) {
        if (evt.target.readyState == FileReader.DONE) { // DONE == 2
            var data = evt.target.result;
            var delimiter = ',';
            var escape = '\n';
            var rows = data.split(escape);
            var tbl = document.createElement('table');
            tbl.style.width = '100%';
            //tbl.setAttribute('border', '1', "green");
            tbl.className = "table table-hover table-condensed dataTable";
            var tbdy = document.createElement('tbody');

            for (index in rows) {
                var tr = document.createElement('tr'); // creating new row 
                var items = rows[index].split(delimiter);
                for (itemindex in items) {
                    var td = "";
                    if (index == 0) {
                        td = document.createElement('th');
                    } else {
                        td = document.createElement('td');
                    }

                    td.appendChild(document.createTextNode(items[itemindex])); // creating new cell 
                    tr.appendChild(td); // add to current tr
                }

                tbdy.appendChild(tr); // add new row (tr) to table 
            }
            tbl.appendChild(tbdy);

            document.getElementById('byte_content').innerHTML=tbl;

        }
    };

    // Progress Loading
    reader.onloadstart = function(e) {
      document.getElementById('progress_bar').className = 'loading';
    };


    reader.onload = function(e) {
      // Ensure that the progress bar displays 100% at the end.
      progress.style.width = '100%';
      progress.textContent = '100%';
      setTimeout("document.getElementById('progress_bar').className='';", 2000);
    }
    var blob = file.slice(start, stop + 1);
    reader.readAsBinaryString(blob);
    document.querySelector('#btnLoad').style.display = "none";
    document.getElementById("btnSubmit").style.display = "block";


}

//Change event if user select a new file.
document.querySelector('#csvfile').addEventListener('change', function (evt) {
        return readBlob();

}, false);
于 2014-02-20T09:25:57.140 回答