Safari HTML5多文件上传错误的任何变通方法?

时间:2013-04-02 14:23:41

标签: html5 safari

经过数周的调整后,我终于放弃了。我无法在safari上修复我的多文件上传,这真的让我感到困扰,因为我的代码在其他浏览器上运行得非常完美,除了在safari上。然后我刚刚发现它不是我的代码有问题。它是一个Safari bug。 Safari 5.1。+无法读取html5多重属性(或类似的东西)。因此用户无法使用多重上传功能,但可以正确上传单个文件。

讨论该问题的几个链接:

https://github.com/moxiecode/plupload/issues/363

file input size issue in safari for multiple file selection

似乎这个bug已经存在了很长一段时间。所以我想知道是否有一些可用的解决方法,你们当中有些人可能知道这一点?因为我找不到任何东西。我发现唯一可用的选项是不为Safari 5.1。+用户使用多个属性。你们有什么更好的想法吗?

更新

Safari 5.1.7 是Apple为Windows操作系统制作的最新版本。他们没有继续构建适用于Windows的Safari的当前版本。无需为我找到此错误的修复程序,因为 Real Safari用户已更新到最新版本的浏览器(无事实),并且只需单独上传那些仍在使用这个过时版本的人,不要牺牲你的应用程序的现代功能。

3 个答案:

答案 0 :(得分:1)

这是一个古老的问题,但是...黑客类型的解决方法如下。

只需删除Safari的多个属性,将其变为MSIE< = 9小弟弟(非XHR)。

其他浏览器不会受到影响。

当Safari最终修复问题时,你所要做的就是删除这个hack :: code并返回标准输入代码。

这里是标准输入样本:

<input class="fileupload-input" type="file" name="files[]" multiple />

jQuery解决方案:

只需将其放在页面上的某个位置,您可以在其中输入文件。

您可以在此处阅读更多内容:How to detect Safari, Chrome, IE, Firefox and Opera browser?

$(document).ready(function () { 
    if (Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor')>0);
         $('.fileupload-input').removeAttr("multiple");
});

PHP解决方案

你需要一些代码来识别浏览器我使用了一个类,我在github(麻省理工学院)有一个 得到它:https://github.com/gavroche/php-browser

 $files = '<input class="fileupload-input" type="file" name="files[]" multiple />';
 if (Browser::getBrowser() === Browser::SAFARI) {
    $files = '<input class="fileupload-input" type="file" name="files[]" />';
 }
echo $files

就是这样。

答案 1 :(得分:0)

似乎还有另一个问题可以搞乱。 iOS Safari多文件上传总是使用名称&#34; image.jpg&#34;对于所有上传的文件。它似乎只在服务器端上传了一个文件,但事实并非如此:它已经上传了所有同名的文件!

因此,解决方法进入服务器端:只需使用新生成的名称更改目标文件名。

我正在使用Flask和Python,因此我使用标准公式。

@app.route("/upload",methods=['POST'])
def upload():
    files = request.files.getlist('files[]')
    for file in files:
        if file and allowed_file(file.filename):
            filename = generate_filename(file.filename)
            file.save( os.path.join(app.config['UPLOAD_FOLDER'], new_album_id, filename))
    return render_template('upload_ok.html')

其中generate_filaname必须是一个创建新文件名的函数,其扩展名与原始文件名相同。例如:

def generate_filename(sample_filename):
    # pick up extension from sample filename
    ext = sample_filename.split(".")[-1]
    name = ''.join( random.SystemRandom().choice(string.letters+string.digits) for i in range(16) )
    return name + "." + ext

当然,在PHP中也可以这样做。

答案 2 :(得分:0)

我在asp.net中遇到了image.jpg问题。它可能使某人受益。我在每个图像文件上附加了一个非唯一的哈希值,以将其绑定到数据库中的记录。除了使用Safari之外,在每个平台(无论如何,我们的用户都在使用)上均可正常运行。我只是将从DateTime的秒部分提取的哈希值和唯一的三位数字符串附加到字符串:

if (!string.IsNullOrEmpty(ViewState["HashId"].ToString()))
        {
            string filepath = Server.MapPath("~/docs/");
            HttpFileCollection uploadedFiles = Request.Files;
            Span1.Text = string.Empty;

            for (int i = 0; i < uploadedFiles.Count; i++)
            {
                HttpPostedFile userPostedFile = uploadedFiles[i];

                try
                {
                    if (userPostedFile.ContentLength > 0)
                    {

                        string timestamp = DateTime.UtcNow.ToString("fff",
                                             CultureInfo.InvariantCulture);

                        //Span1.Text += "<u>File #" + (i + 1) + "</u><br>";
                        //Span1.Text += "File Content Type: " + userPostedFile.ContentType + "<br>";
                        //Span1.Text += "File Size: " + userPostedFile.ContentLength + "kb<br>";
                        //Span1.Text += "File Name: " + userPostedFile.FileName + "<br>";

                        userPostedFile.SaveAs(filepath + "\\" + ViewState["HashId"] + "_" + Path.GetFileName(timestamp + userPostedFile.FileName));
                       // Span1.Text += "Location where saved: " + filepath + "\\" + Path.GetFileName(userPostedFile.FileName) + "<p>";
                        InsertFilename("~/docs/" + ViewState["HashId"] + "_" + Path.GetFileName(timestamp + userPostedFile.FileName), ViewState["HashId"] + "_" + Path.GetFileName(timestamp + userPostedFile.FileName));

                    }
                }
                catch (Exception Ex)
                {
                    Span1.Text += "Error: <br>" + Ex.Message;
                }
            }
            BindImages();
            SetAttchBitTrue();
            Button4.Visible = true;
            AttchStatus.Text = "This Record Has Attachments";
            Button2.Visible = true;
            Button3.Visible = true;
            Panel1.Visible = false;

        }  

也许是一种更好的方法,但是我们只有少数人在数据库中每条记录上载一到两张,也许三张图像。应该可以。