PhantomJS 无法打开未知扩展名的本地文件

PhantomJS cannot open local files of unknown extension

我正在使用 phantomjs 获取 local 文件的屏幕截图。 现在我正在传递一个完全有效的 html 文件:

<!DOCTYPE html><html><head><title>Title of the document</title></head><body>The file name dummy</body></html> 

文件名dummy.hoo

PhantomJS 似乎无法打开它。这是在某处记录的吗?不过,扩展名为 .html.htm 的本地文件没问题。

示例调用(页面路径始终转换为 Uri 方案)

"Phantomjs.exe" --proxy-type=none --ssl-protocol=any --local-to-remote-url-access=true "Scripts\screenshot.js" "file:///D:/dummy.hoo" "base.png"

js简单:

var page = require('webpage').create();
var system = require('system');

if (system.args.length !== 3) {
    console.log('Usage: script.js <URL> <screenshot destination>');
    phantom.exit();
}

page.onResourceError = function(resourceError) {
    page.reason = resourceError.errorString;
    page.reason_url = resourceError.url;
};

page.open(system.args[1], function(status) {
    if (status !== 'success') {
        console.log('Failed to load address '+system.args[1]+' ' + page.reason_url               + ": " + page.reason);
        phantom.exit(-1);
    }
    page.render(system.args[2]);
    phantom.exit();
});

当我复制 Uri 并将其粘贴到 firefox 等时,我可以正确地看到 dummy.hoo 的 html 内容。只有 phantomjs 似乎拒绝渲染它。

对于 dummy.hoo,它总是显示加载地址失败的错误路径,状态为 fail,并且没有通过回调给出原因。 (当我传递一个不存在的url时,我得到了一个适当的理由)

Failed to load address file:///D:/dummy.hoo undefined: undefined

我使用 link 来详细说明此处的错误输出: Debugging PhantomJS webpage.open failures

这是结果:

= onNavigationRequested
  destination_url: file:///D:/dummy.hoo
  type (cause): Other
  will navigate: true
  from page's main frame: true
= onResourceRequested()
  request: {
    "headers": [
        {
            "name": "User-Agent",
            "value": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.9.0 Safari/534.34"
        },
        {
            "name": "Accept",
            "value": "*/*"
        }
    ],
    "id": 1,
    "method": "GET",
    "time": "2015-03-01T16:40:11.080Z",
    "url": "file:///D:/dummy.hoo"
}
= onLoadStarted()
  leaving url: about:blank
= onResourceReceived()
  id: 1, stage: "start", response: {"bodySize":110,"contentType":null,"headers":[{"name":"Last-Modified","value":"Sun, 01 Mar 2015 17:13:02 GMT"},{"name":"Content-Length","value":"110"}],"id":1,"redir
ectURL":null,"stage":"start","status":null,"statusText":null,"time":"2015-03-01T16:40:11.082Z","url":"file:///D:/dummy.hoo"}
= onResourceReceived()
  id: 1, stage: "end", response: {"contentType":null,"headers":[{"name":"Last-Modified","value":"Sun, 01 Mar 2015 17:13:02 GMT"},{"name":"Content-Length","value":"110"}],"id":1,"redirectURL":null,"sta
ge":"end","status":null,"statusText":null,"time":"2015-03-01T16:40:11.082Z","url":"file:///D:/dummy.hoo"}
= onLoadFinished()
  status: fail
Failed to load address file:///D:/dummy.hoo undefined: undefined

我能够在 phantomjs 中找到处理 mime 类型的代码(不同驱动程序的多个位置):

https://github.com/ariya/phantomjs/blob/48fabe06463460d2fb7026d6df9783216e26265c/src/qt/qtwebkit/Source/WebCore/platform/MIMETypeRegistry.cpp#L154

https://github.com/ariya/phantomjs/blob/48fabe06463460d2fb7026d6df9783216e26265c/src/qt/qtwebkit/Source/WebCore/platform/win/MIMETypeRegistryWin.cpp#L80 等等

其背后的要点(呵呵)是本地文件不发送包含 MIME 类型的头信息。因此 Phantomjs 不知道应该调用哪个处理程序来正确呈现内容。我基本上可以将 .jpeg 重命名为 .exe,只要 Web 服务器发送 jpg mime 类型,它就会正确呈现。这是网络中的常见行为,根据任何内容(正则表达式、扩展名等)

重定向 url 部分

Phantoms 没有某种检测文件真实内容的推理(这完全有道理),因此它必须依赖文件扩展名和给定的映射。

所以我知道我必须接受我可以使用 htmlhtm 扩展来渲染 html 数据,没有别的。