【问题标题】:Can I explicitly specify a MIME type in an img tag我可以在 img 标签中明确指定 MIME 类型吗
【发布时间】:2014-05-31 16:31:11
【问题描述】:

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

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

【问题讨论】:

    标签: html image mime-types


    【解决方案1】:

    我过去曾尝试过;但是,根据我的经验,必须在服务器上进行配置。页面中的内容应始终遵循标准文件类型以避免将来出现问题,例如 .png、.gif 和 .jpg。只是我的两分钱。希望对您有所帮助。

    【讨论】:

      【解决方案2】:

      img 元素中没有用于指定媒体类型的属性。如果你使用例如object 元素代替(它也适用于图像,但有一些怪癖),您可以在那里使用 type 属性。但它在 HTML 4.01 中的定义说:“这个属性是可选的,但在指定数据时建议使用,因为它允许用户代理避免加载不受支持的内容类型的信息。如果此属性的值与检索对象时服务器返回的 HTTP Content-Type 不同,则 HTTP Content-Type 优先。”在 HTML5 CR 中,它有点不同,但重点仍然是 type 属性不应该覆盖 HTTP 标头——恰恰相反。

      【讨论】:

        【解决方案3】:

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

        背景

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

        问题

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

        本规范目前没有说明是否或如何检查媒体资源的 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>
        

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

        请记住,任何通过 DOM 操作添加到页面的 new &lt;img&gt; 标签都不会被覆盖,因此您需要自己为这些标签附加监听器。

        CORS

        有趣的是,上面的代码导致 Firefox 和 Chrome 在处理无效图像 URL 时都抱怨CORS

        铬:

        XMLHttpRequest 无法加载 http://www.google.com/notarealfile.png。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,Origin 'null' 不允许访问。响应的 HTTP 状态代码为 404。

        火狐:

        跨域请求被阻止:同源策略不允许读取位于http://www.google.com/notarealfile.png 的远程资源。这可以通过将资源移动到同一域或启用 CORS 来解决。

        但是,Internet Explorer 11 似乎并不在意。这很有效:

        • 不正确的 MIME 类型在 Chrome/Firefox 中可以正常工作,因此不需要创建 XMLHttpRequest
        • 不正确的 MIME 类型无法在 Internet Explorer 上运行,但 XMLHttpRequest 运行时不会出现与 CORS 相关的问题。

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

        【讨论】:

          猜你喜欢
          • 2012-07-26
          • 1970-01-01
          • 2021-01-17
          • 1970-01-01
          • 2019-11-04
          • 1970-01-01
          • 2010-09-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多