html - 我可以在 img 标签中明确指定 MIME 类型吗

标签 html image mime-types

我正在尝试显示 favicon.ico在网页上不是作为快捷方式图标,而是作为页面正文中的图像。在我们的 IE 测试服务器上,图像无法显示,我们发现这是因为服务器上为 .ico 配置的 MIME 类型。文件类型为 image/vnd.microsoft.icon而不是 image/x-icon .

现在,我们能够重新配置服务器并解决问题,但我想知道是否可以在 <img> 中指定要使用的 MIME 类型标记并覆盖特定文件的服务器范围设置?

最佳答案

好消息是,如果您不能依赖服务器提供的类型,则可以强制覆盖图像的 MIME 类型。坏消息是它依赖于 Javascript,并且有点 hacky。

背景

我想使用存储在我的 Gitorious 中的文件HTML 图像标签中的存储库。但是,“原始”文件数据被标记为 text/plain由服务器阻止 Internet Explorer 显示它们。 Firefox 和 Chrome 运行良好,因此我假设它们必须忽略提供的 MIME 类型并根据图像数据找出实际格式。

问题

您不能为 <img> 显式指定 MIME 类型标签。一方面,<img>标签没有 type属性(不同于 <object><embed> ,或 <source><audio> 元素使用的 <video> 标签)。即使他们这样做了,there's no guarantee that it would make any difference :

This specification does not currently say whether or how to check the MIME types of the media resources, or whether or how to perform file type sniffing using the actual file data. Implementors differ in their intentions on this matter and it is therefore unclear what the right solution is. In the absence of any requirement here, the HTTP specification's strict requirement to follow the Content-Type header prevails ("Content-Type specifies the media type of the underlying data." ... "If and only if the media type is not given by a Content-Type field, the recipient MAY attempt to guess the media type via inspection of its content and/or the name extension(s) of the URI used to identify the resource.").

一个可能的解决方案

图像数据可以通过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>

...这是 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);

请记住,任何 <img>不包括通过 DOM 操作添加到页面的标记,因此您需要自己将监听器附加到这些标记。

CORS

有趣的是,上面的代码导致 Firefox 和 Chrome 都提示 CORS处理无效图片 URL 时:

Chrome :

XMLHttpRequest cannot load http://www.google.com/notarealfile.png. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 404.

火狐:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://www.google.com/notarealfile.png. This can be fixed by moving the resource to the same domain or enabling CORS.

然而,Internet Explorer 11 似乎并不关心。这很有效:

  • 不正确的 MIME 类型在 Chrome/Firefox 中工作正常,所以没有 XMLHttpRequest需要制作。
  • 不正确的 MIME 类型将无法在 Internet Explorer 上运行,但 XMLHttpRequest将在没有 CORS 相关问题的情况下运行。

免责声明:正确的做法是让服务器发送正确的 MIME 类型。这是一个相当棘手的解决方法,除非您真的别无选择,否则我不会推荐它。

关于html - 我可以在 img 标签中明确指定 MIME 类型吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23115581/

相关文章:

java - 拍照和使用图像 - 内存不足错误

asp.net-mvc - Asp.Net MVC2 RenderAction 更改页面 mime 类型?

validation - 如何在 Angular 6 中上传之前验证文件

css - 简单易用的 HTML 内容编辑器?

html - 如何在带有链接的无序列表中直接从图像定位文本

c# - 使用黑白图像进行 Blob 跟踪

html - MIME 类型不适用于 SVG

javascript - 仪表板网格 - Chart.JS 和 CSS - 问题扩大两个小水平条形图 - 菜鸟问题

html - 使用 pre 标签时出现问题

image - CIELAB 颜色空间中图像中每个超像素的平均颜色