Mar*_*ney 8 html image mime-types
我试图favicon.ico在网页上显示不是快捷图标,而是在页面正文中显示图像.在我们在IE中的测试服务器上,图像无法显示,我们发现这是因为在服务器上为.ico文件类型配置的MIME 类型而image/vnd.microsoft.icon不是image/x-icon.
现在,我们能够重新配置我们的服务器并解决问题,但我想知道是否可以指定在<img>标签中使用哪种MIME类型并覆盖特定文件的服务器范围设置?
好消息是,如果您不能依赖服务器提供的类型,则可以强制覆盖图像的MIME类型.坏消息是它依赖于Javascript,而且有些笨拙.
我想在HTML图像标签中使用存储在我的Gitorious存储库中的文件.但是,"原始"文件数据被text/plain服务器标记为阻止Internet Explorer显示它们.Firefox和Chrome运行良好,所以我认为他们必须忽略提供的MIME类型,并根据图像数据找出实际格式.
您无法显式指定<img>标记的MIME类型.一方面,<img>标签没有type属性(不像<object>和<embed>,或<source>通过使用标签<audio>和<video>元素).即使他们这样做了,也无法保证会有任何不同:
此规范目前没有说明是否或如何检查媒体资源的MIME类型,或者是否或如何使用实际文件数据执行文件类型嗅探.实施者在这个问题上的意图不同,因此不清楚正确的解决方案是什么.在这里没有任何要求的情况下,HTTP规范严格要求遵循Content-Type标头("Content-Type指定底层数据的媒体类型."......"当且仅当没有给出媒体类型时通过Content-Type字段,接收者可以尝试通过检查其内容和/或用于标识资源的URI的名称扩展来猜测媒体类型.").
可以通过XMLHttpRequest "手动"下载图像数据.一旦实际数据可用于Javascript,就可以通过DOM操作将其插入到页面中.这是一个示例HTML文件:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello, World!</title>
<script src="ieimgfix.js"></script>
</head>
<body>
<img alt="cat" src="https://gitorious.org/vector/vector/raw/0797c6f8faad3426d33d3748b07abd8c77d475a7:bin/media/Floyd-Steinberg_algorithm-original.jpg">
<img alt="apple" src="https://gitorious.org/nanijsore/nanijsore/raw/34b9aae73b5623b9971c8d98878fdbb2a0264476:image/apple.png">
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
......这是ieimgfix.js文件的内容:
"use strict";
// This function is called when any image tag fails to load.
function fixMIME()
{
var img = this;
// First of all, try to guess the MIME type based on the file extension.
var mime;
switch (img.src.toLowerCase().slice(-4))
{
case ".bmp": mime = "bmp"; break;
case ".gif": mime = "gif"; break;
case ".jpg": case "jpeg": mime = "jpeg"; break;
case ".png": case "apng": mime = "png"; break;
case ".svg": case "svgz": mime = "svg+xml"; break;
case ".tif": case "tiff": mime = "tiff"; break;
default: console.log("Unknown file extension: " + img.src); return;
}
console.log("Couldn't load " + img.src + "; retrying as image/" + mime);
// Attempt to download the image data via an XMLHttpRequest.
var xhr = new XMLHttpRequest();
xhr.onload = function()
{
if (this.status != 200) { return console.log("FAILED: " + img.src); }
// Blob > ArrayBuffer: http://stackoverflow.com/a/15981017/4200092
var reader = new FileReader();
reader.onload = function()
{
// TypedArray > Base64 text: http://stackoverflow.com/a/12713326/4200092
var data = String.fromCharCode.apply(null, new Uint8Array(this.result));
img.src = "data:image/" + mime + ";base64," + btoa(data);
};
reader.readAsArrayBuffer(this.response);
};
xhr.open("get", this.src, true);
xhr.responseType = "blob";
xhr.send();
}
// This callback happens after the DOCUMENT is loaded but before IMAGES are.
document.addEventListener("readystatechange", function() {
if (document.readyState != "interactive") { return; }
// Add an error handler callback to all image tags in the document.
var t = document.getElementsByTagName("img");
for (var i = 0; i < t.length; ++i) { t[i].addEventListener("error", fixMIME, false); }
}, false);
Run Code Online (Sandbox Code Playgroud)
请记住,没有涵盖通过DOM操作添加到页面的任何新 <img>标签,因此您需要自己附加监听器.
有趣的是,上面的代码会导致Firefox和Chrome 在处理无效图像URL时抱怨CORS:
XMLHttpRequest无法加载http://www.google.com/notarealfile.png.请求的资源上不存在"Access-Control-Allow-Origin"标头.因此不允许原点'null'访问.响应具有HTTP状态代码404.
跨源请求已阻止:同源策略禁止在http://www.google.com/notarealfile.png上读取远程资源.这可以通过将资源移动到同一域或启用CORS来解决.
但是,Internet Explorer 11似乎并不关心.这很好用:
XMLHttpRequest进行.XMLHttpRequest运行时不会出现与CORS相关的问题.免责声明:正确的事情是让服务器发送正确的MIME类型.这是一个相当hacky的解决方法,除非你别无选择,否则我不会推荐它.
元素中没有用于指定媒体类型的属性img。如果您使用例如object元素(它也适用于图像,但有一些怪癖),您可以type在那里使用该属性。但它在 HTML 4.01 中的定义是: \xe2\x80\x9c 该属性是可选的,但在指定数据时建议使用,因为它允许用户代理避免加载不支持的内容类型的信息。如果该属性的值与检索对象时服务器返回的 HTTP Content-Type 不同,则 HTTP Content-Type 优先。\xe2\x80\x9d 在 HTML5 CR 中,\xe2\x80\x99s 有点不同,但重点仍然是该type属性不会覆盖HTTP headers\xe2\x80\x94,恰恰相反。