javascript - 使用 phantomjs 在本地文件上使用 extjs 代理进行 ajax 调用

标签 javascript unit-testing extjs jasmine phantomjs

我有一个基本的 EXT JS 存储,它使用代理来访问本地 json 文件。

例如

...
proxy: {
    type: 'ajax',
    api: {
        read: 'data/mydata.json'
    },
    reader: {
        type: 'json',
        root: 'datas',
        successProperty: 'success'
    }
} 
...

我想使用 Maven、Jasmine 和 PhantomJS 通过 Atlassian Bamboo(我的 CI 服务器)构建和测试我的项目。

当我在本地执行 PhantomJS 时,像这样:

$ phantomjs "c:\phantomjs-1.6.1\examples\run-jasmine.js" run-tests.html

我得到以下输出:

'waitFor()' finished in 422ms.
 4 specs, 2 failures in 0.075s

发生这种情况是因为 PhantomJS 无法使用 file:// 协议(protocol)为 EXT JS 代理加载本地文件。

我正在关注 this例如,我想知道是否可以模拟我的代理响应,以便我可以在本地(在我的 Bamboo 服务器上)将 PhantomJS 与测试 html 文件一起使用,而不必将项目托管在像 Apache 这样的 Web 服务器中(我的外部依赖项)将不得不使用 Maven 进行管理)。

如果没有,我可以使用任何其他机制(内置于 Jasmine、PhantomJS 或其他方式)来实现这一目标吗?

最佳答案

从文件系统加载时,实际上 可以使用 PhantomJS 执行 XHR!

直接来自 the PhantomJs wiki :

--web-security=[yes|no] disables web security and allows cross-domain XHR (default is yes)

另见 this issue report for PhantomJs这可能会阐明这个主题。

Sencha 的“sencha create jsb”命令使用 PhantomJs(而 Ext.Loader 使用 XHR)并且它支持从文件系统加载。

name: 'app-entry',
alias: 'a',
description: 'The file or URL path to your application\'s HTML entry point',

checkout [senchasdktools]/compat/command/src/modules/GenerateJSB.js[senchasdktools]/compat/command/scripts/phantomjs-jsb.js

不过,我没有看到任何与提到的 web-security 开关相关的内容。也许他们使用自定义 phantomJs 构建。

更新 此代码片段允许对文件系统发出 XHR 请求。使用最新版本的 phantomJs (1.6.1/Windows) 测试:

var page = new WebPage();
page.settings.localToRemoteUrlAccessEnabled = true;

更新2 这是一个工作示例。

将所有内容放在同一个文件夹中,添加一个包含一些内容的test.txt文件,然后运行

phantomjs script.js test.html

phantomjs 脚本 (script.js):

var fs = require('fs');

var appLocation = phantom.args[0];

var page = new WebPage();

page.settings.localToRemoteUrlAccessEnabled = true;
page.settings.ignoreSslErrors = true;

page.onConsoleMessage = function(message, url, lineNumber) {
    console.log((url ? url + " " : "") + (lineNumber ? lineNumber + ": " : "") + message);
};

page.onError = function (msg, trace) {
    console.log(msg);
    trace.forEach(function(item) {
        console.log('  ', item.file, ':', item.line);
    });
    phantom.exit(1);
};

if (!/^file:\/\/|http(s?):\/\//.test(appLocation)) {
    appLocation = 'file:///' + fs.absolute(appLocation).replace(/\\/g, '/');
}

page.open(appLocation, function(status) {
    if (status !== 'success') {
        error("Failed opening: '" + appLocation + "'. Please verify that the URI is valid");
    }

    page.evaluate(function() {
        window.onerror = function(message, url, lineNumber) {
            console.log((url ? url + " " : "") + (lineNumber ? lineNumber + ": " : "") + message);
        };

    });

    timer = setInterval(function() {
        console.log('Timeout!');
        phantom.exit(1);
    }, 2000);
});

HTML 文件(test.html):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html class="x-border-box x-strict">
<head>
    <title>Test</title>
    <script type="text/javascript">
    var xhr = new XMLHttpRequest();

    try {
        xhr.open('GET', 'test.txt', false);
        xhr.send(null);
    } catch (e) {
        console.log('cross origin?');
    }

    console.log('status', xhr.status);
    console.log('response', xhr.responseText);

    </script>
</head>
<body class="x-body">
</body>
</html>

Chrome 和 --disable-web-security 和 ExtJs

我实际上使用 --disable-web-security 作为 Google Chrome 的启动参数,在开发期间从文件系统运行我的 webapp,它在那里工作(启动时必须运行其他 Chrome 进程 Chrome )。 Chrome 将显示一条警告消息,指出您正在使用不受支持的选项(顶部的黄色通知栏)。

但是,为了让 Ext 在这样的设置中工作,我需要为 Ext.Connection 添加一个额外的补丁,以解决两个问题: (1) xhr.status 在加载文件系统资源时总是0。 Ext 不会将此状态代码视为成功。当 Ext 在 PhantomJs 中运行时,有专门的代码来处理这个问题——这就是它应该在那里工作的原因。

(2) 当 URL 包含查询字符串时,Chrome 无法加载文件系统资源。在文件系统模式下,我覆盖了 Connection 类以去除所有 url 参数。

关于javascript - 使用 phantomjs 在本地文件上使用 extjs 代理进行 ajax 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11933044/

相关文章:

javascript - 将脚本传递给 innerHTML

javascript - 通过 Angular http 请求发布文件

java:在调度程序内对 lambda 表达式进行单元测试

java - 为此方法编写单元测试用例返回 RxJava Future

javascript - 带有多行标签的按钮带来列布局的麻烦

javascript - 如何在悬停时突出显示文本

javascript - 将索引传递给 jQuery

unit-testing - hbase-testing-utility 的 sbt 依赖管理问题

javascript - EXTJS 如何交换两个子节点的顺序?

javascript - Ext4 重载树