在 iOS 上未选择文件时,JavaScript 使用 FormData 和 jQuery 的 ajax 上传文件返回错误 500

Posted

技术标签:

【中文标题】在 iOS 上未选择文件时,JavaScript 使用 FormData 和 jQuery 的 ajax 上传文件返回错误 500【英文标题】:JavaScript Using FormData and jQuery's ajax for uploading files returns error 500 when no file is selected on iOS 【发布时间】:2018-07-30 09:01:37 【问题描述】:

我正在使用 FormData 和 jQuery 的 ajax 以表单形式上传文件。 一切正常,除非在 ios 上没有选择文件,然后我从 php 脚本中收到错误 500。

在 PC 和 android 上,无论是否选择了文件,它都可以正常工作,但在 iOS 上,它只有在选择文件时才有效(不需要选择文件)。 我使用的是最新的 iOS 11.4.1。

这是我在提交表单时调用的代码:

var form = this;
var data = new FormData(form);

var options = 
    url: $(form).attr('action'),
    data: data,
    type: $(form).attr('method'),
    cache: false,
    contentType: false,
    processData: false,
    complete: function(r)
        if(r.status == 200)
            var response = r.responseJSON;

            showErrors(form, response.errors);
            $.each(response.actions, handleAction.bind(form));
        else
            showErrors(form, ['Vyskytla sa neočkávaná chyba, skúste znova neskôr']);
        
    
;
if(data.fake)
    opts.xhr = function()
        var xhr = jQuery.ajaxSettings.xhr();
        xhr.send = xhr.sendAsBinary;
        return xhr;
    
    opts.contentType = 'multipart/form-data;boundary='+data.boundary;
    opts.data = data.toString();


$.ajax(options);

有一部分代码打印了来自服务器的响应,这就是响应:

"readyState":4,"responseText":"\n\n\n\n
Internal Server Error

\n
The server encountered an internal error or\nmisconfiguration and was unable to complete\nyour request.

\n
Please contact the server administrator at \n ssl@atlantis.sk to inform them of the time this error occurred,\n and the actions you performed just before this error.

\n
More information about this error may be available\nin the server error log.

\n\n","status":500,"statusText":"Internal Server Error"

【问题讨论】:

“有关此错误的更多信息可能在服务器错误日志中可用。”这是服务器端错误,您需要在服务器上进行调试和/或向我们展示您的后端代码。 由于这个错误,我只将这段代码放在 PHP 脚本中:header('Content-Type: application/json');echo json_encode($_POST, $_FILES);。而且我不确定服务器错误日志的位置。 /var/log/apache2/error.log下看看。 我无法访问主机的文件系统,但根据 phpinfo 甚至没有设置 error_log 值。 您确实需要一台可以完全访问调试服务器端代码的开发机器,否则如果您甚至看不到错误消息,那将是大量的试验和错误。另外,查看json_encode() 的手册,第二个参数是附加选项。 php.net/manual/en/function.json-encode.php 【参考方案1】:

我终于找到了解决问题的方法,它不在服务器端。 看起来 FormData 将 iOS 上的一个空 File 对象的数组放入数据变量中,服务器无法处理。

我将 JS 编辑成这样:

var data = new FormData(form);
$.each($(form).find('input[type="file"]'), function()
    var name = $(this).attr('name');
    var files = $(this).prop('files');

    if(files.length == 0)
        data.set(name, null);
    
);

【讨论】:

以上是关于在 iOS 上未选择文件时,JavaScript 使用 FormData 和 jQuery 的 ajax 上传文件返回错误 500的主要内容,如果未能解决你的问题,请参考以下文章

在选择器视图上未按下按钮

如何在 ios 设备上未启动本机应用程序时进行调试

首次访问时,iOS 设备上未加载 jwplayer 视频

Facebook 请求配置文件 Graph API 无法在 iOS 7 本机 facebook 上未登录

设备上未收到 iOS 推送通知

iOS-应用程序退出时在 Crashlytics 上未收到崩溃