为啥 PHP 没有为 json 文件返回正确的 mime?

Posted

技术标签:

【中文标题】为啥 PHP 没有为 json 文件返回正确的 mime?【英文标题】:Why is PHP not returning correct mime for json files?为什么 PHP 没有为 json 文件返回正确的 mime? 【发布时间】:2016-12-30 04:40:06 【问题描述】:

我知道 json 文件的正确 MIME 类型是 applicattion/json,这可以通过这篇帖子 What is the correct JSON content type? 确认。

但是,我想知道为什么我的 php 安装返回 text/plain。在解析 json 文件之前,我需要测试正确的 mime。

我有以下代码

$fileinfo = new finfo();
$fileType = $fileinfo->file( $_FILES['tmp_name'], FILEINFO_MIME_TYPE );

其中$fileType 返回text/plain 而不是applicattion/json

同样,$_FILES['type'] 返回 application/octet-stream 而不是 applicattion/json

我错过了什么?

编辑

我正在通过 jQuery ajax 发送文件:

var formData = new FormData( $(form)[0] );
var jsonFile = $( 'input:file[name=contents]', form ).get(0).files[0];

formData.append( 'jsonFile', jsonFile );

$.ajax( 

    type: 'POST',
    url: 'url',
    data: formData,
    dataType:'json',
    enctype : 'multipart/form-data',
    processData: false,
    contentType : false,
    encode:true,
)

【问题讨论】:

文件内容是什么? @StephenAdelakun 对象 // 文件?他们不一样.. 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:How to create a Minimal, Complete, and Verifiable example。 一个 JSON 文件是 plain/text,但是当它通过 Internet 传输以允许接收代码将其区分为特定的 JSON 纯文本文件时,它前面有一个标题,说它是 application/json。该 mime 类型未包含在文件中 Guys OP 正在测试 $_FILES['tmp_name'] 临时下载文件。 没有与 THAT 或任何其他文件关联的 mime 类型 这里没有要解决的问题 【参考方案1】:

finfo 通过内容而不是文件扩展名来识别文件类型。

只有带有签名的文件才能被正确识别。否则,将根据其内容将其标识为text/plain(ASCII)或application/octet-stream(二进制)。

不幸的是,JSON 编码的内容没有签名,因此被标识为 text/plainapplication/octet-stream

如需进一步阅读,请访问:-

List of file signatures

希望这会有所帮助。

[编辑 1] 下面是我的测试脚本。干杯。

$filename = "test.json";

$finfo = finfo_open(FILEINFO_MIME_TYPE);

file_put_contents($filename, "<?php \n");
printf("%s\n", finfo_file($finfo, $filename));

file_put_contents($filename, "@echo off\n");
printf("%s\n", finfo_file($finfo, $filename));

file_put_contents($filename, json_encode(array("a" => "1")));
printf("%s\n", finfo_file($finfo, $filename));

file_put_contents($filename, "\xff");
printf("%s\n", finfo_file($finfo, $filename));

finfo_close($finfo);

【讨论】:

对于 SO 上的回答者来说,在没有耐心了解 OP 想要什么的情况下跳到 OP 并注销是很常见的。这是一个例外。【参考方案2】:

我不确定您的实际问题是什么。它指的是获取某些 MIME 类型的两种方式。

Fileinfo 使用 libmagic。顾名思义,这里发生了魔法。本质上,它查看文件并尝试猜测文件可能是什么类型。如果它以GIF89a 开头,它将报告图像/gif。猜测通常是错误的,但已经足够了。

$_FILES 包含客户端(Web 浏览器)正在发送的信息。里面的类型就是浏览器的东西。这通常是完全没用的。

如果您需要精确的类型,您必须自己确保这一点。如何执行此操作取决于文件来自何处以及您打算做什么。即,如果这来自值得信赖的管理员,您可能会查看文件扩展名。对于从不太受信任的用户上传的图像(我希望您不打算接受从不完全受信任的用户上传的 javascript 文件来执行),一个好方法是实际尝试打开图像甚至重新编码它(即摆脱 exif 数据)

【讨论】:

我也不确定您是否清楚地阅读了我的问题。 json 文件的正确 mime 类型是 application/json 我需要对此进行测试,那么为什么尽管使用 .json 保存文件,但 PHP 没有返回此文件,该文件包含格式正确的 json 内容并使用不同的测试方法返回text/plain.【参考方案3】:

如果您在 *nix 系统上,您可以随时尝试使用 file 命令。

【讨论】:

这与“*nix”到底有什么关系? 我不认为(知道)在 *dows 系统上是否有任何 file 命令...

以上是关于为啥 PHP 没有为 json 文件返回正确的 mime?的主要内容,如果未能解决你的问题,请参考以下文章

为啥数组响应没有使用 PHP MySQL API 进入 JSON

php curl的正确使用方法

为啥没有为 java 枚举正确生成 Json?

将 PHP 数组转换为对象的 JSON 数组

使用 Kotlin 数据类的 Json 解析器正确返回 json 数据,但是为啥解析器(MockK)的单元测试会失败?

PHP mysqli_fetch_assoc 没有返回正确的值