最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Using phantomjs to make ajax calls using extjs proxy on local file - Stack Overflow

programmeradmin1浏览0评论

I have a basic EXT JS store that uses a proxy to access a local json file.

e.g.

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

I want to use Maven, Jasmine and PhantomJS to build and test my project with Atlassian Bamboo (my CI server).

When I execute PhantomJS locally, like so:

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

I get the following output:

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

This is happening because PhantomJS can't manage to load local files using file:// protocol for the EXT JS proxy.

I'm following this example, and am wondering whether it's possible to mock my proxies response so that I can use PhantomJS locally (on my Bamboo server) with the test html file, rather than having to host the project in a web server like Apache (an external dependency I will have to manage with Maven).

If not, are there any other mechanisms (built into Jasmine, PhantomJS, or otherwise), that I can use to achieve this?

I have a basic EXT JS store that uses a proxy to access a local json file.

e.g.

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

I want to use Maven, Jasmine and PhantomJS to build and test my project with Atlassian Bamboo (my CI server).

When I execute PhantomJS locally, like so:

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

I get the following output:

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

This is happening because PhantomJS can't manage to load local files using file:// protocol for the EXT JS proxy.

I'm following this example, and am wondering whether it's possible to mock my proxies response so that I can use PhantomJS locally (on my Bamboo server) with the test html file, rather than having to host the project in a web server like Apache (an external dependency I will have to manage with Maven).

If not, are there any other mechanisms (built into Jasmine, PhantomJS, or otherwise), that I can use to achieve this?

Share Improve this question edited Sep 13, 2017 at 3:41 wulfgarpro asked Aug 13, 2012 at 11:04 wulfgarprowulfgarpro 6,93412 gold badges75 silver badges112 bronze badges 1
  • FYI, I'm using phantomjs 1.6.1. – wulfgarpro Commented Aug 25, 2012 at 7:43
Add a ment  | 

3 Answers 3

Reset to default 9

It actually is possible to do XHR with PhantomJS when loading from the file system!

Straight from the PhantomJs wiki:

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

Also see this issue report for PhantomJs which might shed some light on this topic.

Sencha's 'sencha create jsb' mand uses PhantomJs (and Ext.Loader uses XHR) and it supports loading from the file system.

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

Checkout [senchasdktools]/pat/mand/src/modules/GenerateJSB.js and [senchasdktools]/pat/mand/scripts/phantomjs-jsb.js.

I don't see anything related to the mentioned web-security switch though. Maybe they use a custom phantomJs build.

UPDATE This code fragment allows XHR requests to the file system. Tested with the latest version of phantomJs (1.6.1/Windows):

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

UPDATE2 This is a working example.

Put everything in the same folder, add a test.txt file with some content, then run

phantomjs script.js test.html

phantomjs script (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 file (test.html):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3/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 and --disable-web-security and ExtJs

I am actually using --disable-web-security as startup parameter to Google Chrome to run my webapp form the filesystem during development and it works there (no other Chrome processes must be running when starting Chrome). Chrome will display an alert message stating that you are using an unsupported option (yellow notification bar at the top).

However, for Ext to work in a setup like this I required an additional patch to Ext.Connection in order to fix two issues: (1) xhr.status is always 0 when loading a file system resource. Ext does not consider this status code as successful. There is code dedicated to handling this when Ext is running in PhantomJs - that's why it should work there.

(2) Chrome failed loading file system resources when the URL contains a query string. I override the Connection class to strip all url params when in filesystem mode.

that is browser, and WebKit, restriction (security) and there is no way to bypass except if you run your own webserver. There is easy way with nodejs. Its about few lines of code to run server on some port on local machine.

Just create server.js as below and run it with node server.js before you run phantomjs

var http = require('http');
var fs=require('fs');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.end(fs.readFileSync(__dirname + req.url, 'utf8')); 
}).listen(3000, '127.0.0.1');
console.log('Server running at http://127.0.0.1:3000/');

Keep this file in project root or update line

res.end(fs.readFileSync(__dirname + req.url, 'utf8')); 

__dirname is path of folder in which server.js lives and is set by node process....

now you can keep data/*.json or even create mock data in node ;)

===Update====

After reading PhantomJS documentation I found that you can do same as above without nodejs. Apparently, PhanotmJS has all above modules included

Consider to check:

  • http://code.google./p/phantomjs/wiki/Interface#WebServer_Module
  • http://code.google./p/phantomjs/wiki/Interface#Filesystem_Module

And you will be good to go.

I wrote 2 repos for dealing with ExtJS 4 for unit testing using Karma test runner/ Jasmine 1.x and 2.0 versions and dealing with Async Issues: here they are: https://github./cgauthier/karma_jasmine_1_extjs4 and https://github./cgauthier/karma_jasmine_2_extjs4.

发布评论

评论列表(0)

  1. 暂无评论