英文:
JavaScript FileReader API isn't respecting accept type
问题
我正在使用JavaScript的FileReader来在我的Web应用程序中上传文件。我想限制接受的文件类型只能是.pem
和.key
。然而,我注意到我也能上传.crt
和.cer
文件。我的实现有什么问题吗?我正在使用以下代码:
<input
type="file"
accept=".key, .pem"
/>
英文:
I am using the JavaScript FileReader to upload files in my web application. I want to restrict the accepted file types to only .pem
and .key
. However, I noticed that I am able to upload .crt
and .cer
files as well. Is there something wrong with my implementation? I am using the following code:
<input
type="file"
accept=".key, .pem"
/>
答案1
得分: 2
另一个答案是正确的,您不应该依赖accept
属性来安全地过滤文件的类型,但可以注意到这实际上是一个Chrome错误(可能是特定于macOS的)。根据规范,如果逗号分隔的令牌列表中的令牌是:
> 第一个字符是U+002E FULL STOP字符(.)的字符串。
> 表示接受具有指定文件扩展名的文件。
然而,似乎Chrome实际上查看操作系统注册表,因此如果在您的操作系统上.pem
文件与.cer
文件一起注册,即使您只设置了accept=" .pem"
,它们也都会被接受。
这在我的macOS系统上是这种情况,其中lsregister -dump
给出了以下结果:
type id: public.x509-certificate (0xc634)
bundle: CoreTypes (0x1d34)
uti: public.x509-certificate
localizedDescription: "ar" = "شهادة (X.509)", "ca" = "certificat (X.509)", "cs" = "certifikát (X.509)", "da" = "certifikat (X.509)", "de" = "Zertifikat (X.509)", "el" = "πιστοποιητικό (X.509)", "en" = "certificate (X.509)", "en_AU" = "certificate (X.509)", "en_GB" = "certificate (X.509)", "es" = "certificado (X.509)", "es_419" = "certificado (X.509)", "fi" = "varmenne (X.509)", "fr" = "certificat (X.509)", "fr_CA" = "certificat (X.509)", "he" = "אישור (X.509)", "hi" = "सर्टिफ़िकेट (X.509)", "hr" = "certifikat (X.509)", "hu" = "tanúsítvány (X.509)", "id" = "sertifikat (X.509)", "it" = "certificato (X.509)", "ja" = "証明書(X.509)", "ko" = "인증서(X.509)", "LSDefaultLocalizedValue" = "certificate (X.509)", "ms" = "sijil (X.509)", "nl" = "certificaat (X.509)", "no" = "sertifikat (X.509)", "pl" = "certyfikat (X.509)", "pt_BR" = "certificado (X.509)", "pt_PT" = "certificado (X.509)", "ro" = "certificat (X.509)", "ru" = "сертификат (X.509)", "sk" = "certifikát (X.509)", "sv" = "certifikat (X.509)", "th" = "ใบรับรอง (X.509)", "tr" = "sertifika (X.509)", "uk" = "сертифікат (X.509)", "vi" = "chứng nhận (X.509)", "zh_CN" = "证书(X.509)", "zh_HK" = "證書(X.509)", "zh_TW" = "憑證(X.509)"
flags: active public apple-internal exported core trusted (0000000000000077)
conforms to: public.data
tags: .cer, .der, .crt, .pem, application/x-x509-ca-cert
正如您所看到的,所有这些扩展都共享相同的type id
,因此在我的Chrome中它们都是等效的。在Firefox中情况并非如此,它确实遵守规范,并根据扩展名进行真正的过滤。
(注意:我认为没有任何东西会影响这些扩展。)
不幸的是,您无法做太多事情,因为使用MIME类型(application/x-x509-ca-cert
)将产生完全相同的结果。最好的方法是标记链接的问题,希望他们能在某一天修复它。
英文:
The other answer is right that you shouldn't rely on the accept
attribute to safely filter the file's types, but one might note that this is actually a Chrome Bug (probably macOS specific).
According to the specs, if the token in the list of comma separated tokens is
> A string whose first character is a U+002E FULL STOP character (.).
> [It i]ndicates that files with the specified file extension are accepted.
However it seems that Chrome does look at the OS registry instead, and thus if on your OS .pem
files are registered along with .cer
files, they'll both be accepted even if you did only set accept=".pem"
.
This is the case on my macOS system where an lsregister -dump
gives
type id: public.x509-certificate (0xc634)
bundle: CoreTypes (0x1d34)
uti: public.x509-certificate
localizedDescription: "ar" = "شهادة (X.509)", "ca" = "certificat (X.509)", "cs" = "certifikát (X.509)", "da" = "certifikat (X.509)", "de" = "Zertifikat (X.509)", "el" = "πιστοποιητικό (X.509)", "en" = "certificate (X.509)", "en_AU" = "certificate (X.509)", "en_GB" = "certificate (X.509)", "es" = "certificado (X.509)", "es_419" = "certificado (X.509)", "fi" = "varmenne (X.509)", "fr" = "certificat (X.509)", "fr_CA" = "certificat (X.509)", "he" = "אישור (X.509)", "hi" = "सर्टिफ़िकेट (X.509)", "hr" = "certifikat (X.509)", "hu" = "tanúsítvány (X.509)", "id" = "sertifikat (X.509)", "it" = "certificato (X.509)", "ja" = "証明書(X.509)", "ko" = "인증서(X.509)", "LSDefaultLocalizedValue" = "certificate (X.509)", "ms" = "sijil (X.509)", "nl" = "certificaat (X.509)", "no" = "sertifikat (X.509)", "pl" = "certyfikat (X.509)", "pt_BR" = "certificado (X.509)", "pt_PT" = "certificado (X.509)", "ro" = "certificat (X.509)", "ru" = "сертификат (X.509)", "sk" = "certifikát (X.509)", "sv" = "certifikat (X.509)", "th" = "ใบรับรอง (X.509)", "tr" = "sertifika (X.509)", "uk" = "сертифікат (X.509)", "vi" = "chứng nhận (X.509)", "zh_CN" = "证书(X.509)", "zh_HK" = "證書(X.509)", "zh_TW" = "憑證(X.509)"
flags: active public apple-internal exported core trusted (0000000000000077)
conforms to: public.data
tags: .cer, .der, .crt, .pem, application/x-x509-ca-cert
As you can see, all these extensions share the same type id
, and thus in my Chrome they're all equivalent. This is not the case e.g. in Firefox, which does respect the specs and really filter by extension.
(Note: I don't think I've got anything that affected these extensions.)
Unfortunately there isn't much you can do about it, since using the MIME type (application/x-x509-ca-cert
) would have the exact same result. The best would be to star the linked issue and hope they can fix it some day.
答案2
得分: 1
accept
属性并不按照你期望的方式工作。以下是来自MDN文档的相关摘录:
accept
属性不会验证所选文件的类型;它只是为了提示浏览器引导用户选择正确的文件类型。在大多数情况下,用户仍然可以切换文件选择器中的选项,以覆盖此提示并选择任何文件,甚至选择不正确的文件类型。因此,你应该确保预期的要求在服务器端进行验证。
英文:
The accept
attribute doesn't work in the way it seems you expect it to. Here's a relevant excerpt from MDN's documentation:
> The accept attribute doesn't validate the types of the selected files; it provides hints for browsers to guide users towards selecting the correct file types. It is still possible (in most cases) for users to toggle an option in the file chooser that makes it possible to override this and select any file they wish, and then choose incorrect file types.
>
> Because of this, you should make sure that expected requirement is validated server-side.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论