You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

桌面端音频上传正常,移动端返回octet-stream提示格式不符求排查

解决移动端音频上传MIME类型识别错误的问题

我完全懂你现在的困扰——桌面端传音频一切顺畅,换到手机上就老是跳格式错误提示,查了才发现MIME类型变成了octet-stream。这其实是移动端浏览器的常见问题:不少手机浏览器不会正确识别音频文件的MIME类型,反而把它当成通用的二进制流返回,直接绕开了你当前的校验逻辑。

问题根源

你现在的代码完全依赖$_FILES['audio']['type']判断文件类型,但这个值是客户端浏览器提供的,并不是文件的真实MIME类型。移动端浏览器经常会返回不准确的结果,比如把音频文件识别成application/octet-stream,导致你的格式校验直接触发错误。

修复方案

方案1:结合文件扩展名做双校验

既然客户端的MIME不可靠,我们可以同时检查文件扩展名,用双保险来判断是否为合法音频格式。

修改后的代码如下:

if (isset($_POST['submit_atrack'])) {
    $fileinfo = PATHINFO($_FILES["audio"]["name"]);
    $newFilename = $fileinfo['filename'] . uniqid($usr_idLogged) . "." . $fileinfo['extension'];
    $location = 'atracks/' . $newFilename;
    
    // 允许的MIME类型(兼容移动端返回的octet-stream)
    $allowedMimes = array('audio/mpeg', 'audio/ogg', 'audio/wav', 'audio/mp3', 'application/octet-stream');
    // 允许的文件扩展名
    $allowedExtensions = array('mp3', 'ogg', 'wav', 'mpeg');
    $tamanho_max = 500000000; //500 mb

    if (empty($_FILES['audio']['name'])) {
        $upload_empty = urlencode("empty");
        header("Location:playlist?newtrack=" . $upload_empty . "&playlist=" . $selectedPlaylist);
        exit;
    } 

    // 先校验扩展名,再结合MIME类型判断(给octet-stream开绿灯)
    $fileExt = strtolower($fileinfo['extension']);
    $isValidExt = in_array($fileExt, $allowedExtensions);
    $isValidMime = in_array($_FILES['audio']['type'], $allowedMimes);

    if (!$isValidExt || (!$isValidMime && $_FILES['audio']['type'] !== 'application/octet-stream')) {
        $upload_incorrectformat = urlencode("incorrectext");
        header("Location:playlist?newtrack=" . $upload_incorrectformat . "&playlist=" . $selectedPlaylist);
        exit;
    } 

    if ($_FILES['audio']['size'] >= $tamanho_max) {
        $upload_maxsize = urlencode("maxsizereached");
        header("Location:playlist?newtrack=" . $upload_maxsize . "&playlist=" . $selectedPlaylist);
        exit;
    } 

    // 先执行文件移动,再写入数据库(避免数据库存了路径但文件没传成功)
    if (move_uploaded_file($_FILES["audio"]["tmp_name"], $location)) {
        $atitle = mysqli_real_escape_string($connection, $_POST['atitle']);
        $atag = mysqli_real_escape_string($connection, $_POST['atag']);
        $atagcolor = mysqli_real_escape_string($connection, $_POST['atagcolor']);
        mysqli_query($connection,"INSERT INTO tbl_users_atrack (atrack_title, atrack_path, atrack_tag, atrack_tagColor, atrack_playlistId) VALUES ('$atitle', '$location', '$atag', '$atagcolor', '$selectedPlaylist')");
        
        $upload_success = urlencode("success");
        header("Location:playlist?newtrack=" . $upload_success . "&playlist=" . $selectedPlaylist);
    } else {
        // 处理文件移动失败的情况
        $upload_error = urlencode("uploaderror");
        header("Location:playlist?newtrack=" . $upload_error . "&playlist=" . $selectedPlaylist);
    }
    exit;
}

方案2:用finfo检测真实文件类型(更安全)

如果想要更严谨的校验,推荐用PHP的finfo扩展读取文件的真实MIME类型——这个是从文件内容分析出来的,完全不受客户端返回值的影响,能彻底杜绝伪造文件类型的问题。

核心代码示例:

// 初始化finfo对象,用于读取文件真实MIME类型
$finfo = new finfo(FILEINFO_MIME_TYPE);
// 获取上传文件的真实MIME类型
$realMimeType = $finfo->file($_FILES["audio"]["tmp_name"]);

// 定义允许的真实音频MIME类型
$allowedRealMimes = array('audio/mpeg', 'audio/ogg', 'audio/wav');

// 替换原来的MIME校验逻辑
if (!in_array($realMimeType, $allowedRealMimes)) {
    $upload_incorrectformat = urlencode("incorrectext");
    header("Location:playlist?newtrack=" . $upload_incorrectformat . "&playlist=" . $selectedPlaylist);
    exit;
}

把这段逻辑替换你原来依赖$_FILES['audio']['type']的校验,就能彻底解决移动端的识别问题,同时提升上传的安全性。

额外小提示

  • 确认服务器上atracks目录的写入权限是否正常,避免出现文件移动失败的情况。
  • 如果你用的是较老的PHP版本,finfo可能需要手动在php.ini里开启,不过现在大部分服务器环境默认已经启用了。

内容的提问来源于stack exchange,提问作者Luann Sousa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:41:54