If one must load and parse an XML resource from a user/PW-protected URL you cannot just use an MSXML DOM.Load() as far as I can tell. There is no place to specify the credentials.
Yet if you use XMLHTTPRequest to obtain and parse the resource into a DOM (via its .responseXML property) you have nowhere to specify a value for the .resolveExternals property.
This more or less works out when you use MSXML 3, 4, (or even 5) where it defaults to True, however in MSXML 6 it defaults to False:
resolveExternals Property:
In MSXML 3.0, MSXML 4.0, and MSXML 5.0 the default resolveExternals
value is True. In MSXML 6.0, the default setting is False.
If this property is set to False, no external includes and imports
will be resolved.
Is there a way around this that I am not seeing? Normally I need the externals resolved, especially when dealing with XSDs or WSDLs.
Or am I fooling myself, and perhaps .resolveExternals never applies when using XMLHTTPRequest (only DOM.Load() calls)?
Have you tried something like this?
xmlhttp.responseXML.resolveExternals = true;
xmlhttp.responseXML.setProperty("ProhibitDTD", false);
The only thing is the solution may only work with MSXML XMLHTTP ActiveX object.
Edit: here is a concrete sample with IE9:
var xmlhttp = new ActiveXObject("MSXML2.XMLHTTP.6.0");
// var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "sample.xml", false);
xmlhttp.responseXML.async = false;
xmlhttp.responseXML.resolveExternals = true;
xmlhttp.responseXML.validateOnParse = false;
xmlhttp.responseXML.setProperty("ProhibitDTD", false);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readystate == 4 && xmlhttp.status == 200) {
alert(xmlhttp.responseXML.xml);
}
}
xmlhttp.send();
sample.xml
<!DOCTYPE data SYSTEM "sample.dtd"><data>&ent;</data>
sample.dtd
<!ENTITY ent "Hello world!">
If you run the above cod with IE9, you'll successfully get the entity resolved. However, if you switch to the commented out XMLHttpRequest, you will fail.
PS: I thought you were talking about scripting inside IE, and there is a Trident native component called XMLHttpRequest which is quite different from XmlHttp ActiveX component. However, if you are referring to IXMLHttpRequest COM interface residing in MSXML6.DLL, you can translate the above code into C++ with ease.
Related
In the Extjs classic framework we use Ext.form.Panel to initiate a file download. In the Modern framework I have been unable to get Ext.form.Panel to do the same. So how can I perform a simple file download (of a potentially large file) in the Modern framework. I would rather not have to change the server side code.
This is the code we use in Classic
params={};
params.doc_path=rec.get('server_path');
params.doc_link_name=rec.get('name');
var form = Ext.create('Ext.form.Panel', {
standardSubmit: true,
renderTo: Ext.getBody(),
url: '/document/download',
method: 'POST',
timeout: 120
});
// Call the submit to begin the file download.
// Note that neither Success nor Failure are ever called
form.submit({
params: params
});
This is the server side code in our ruby server
def download
# A small helper to download the file passed in doc_path
send_file params["doc_path"], type: 'application/octet-stream', disposition: 'attachment', filename: params["doc_link_name"]
end
If we try that in Modern our server does not receive the correct url. (We get a routing error).
File upload using a form in Modern works just the same as Classic, so why doesn't the file download work the same?
Does anyone have some sample code on how to use Ext.exporter.file to download a file from a server? I have read the docs and just got lost. And in any case when I put in a require for Ext.exporter.file I get a 404 not found error, so that is out of the question.
I just need click and forget so no need to track success or failure.
Thanks to Imagine-breaker for his answer in this post I implemented this function:
downloadURI: function(uri, name) {
var link = document.createElement("a");
if(!name)name="";
link.setAttribute('download', name);
link.href = uri;
document.body.appendChild(link);
link.click();
link.remove();
}
and call it like this
lfg.downloadURI('/document/download?doc_path=' + encodeURIComponent(rec.get('server_path')),rec.get('name'));
Server side code remains exactly as is. I might implement this in our Classic version of the app as well - it seems so much simpler.
I'm working on a map project under React, using react-leaflet, and leaflet-pixi-overlay. Markers are implemented using the PIXI overlay (React 16.13.1, pixi.js 5.3.0, leaflet 1.6.0, leaflet-pixi-overlay 1.8.1).
I am struggling a bit with the PIXI documentation. I would like to use this PIXI.Texture.fromURL method (http://pixijs.download/release/docs/PIXI.Texture.html#.fromURL)
However neither my VS Code environment, nor my compiled source can access this method.
I am using instead PIXI.Texture.from(imageUrl), as well as PIXI.Texture.fromLoader(imageUrl). Both seem to work, but I don't get the difference between the two? The docs don't show these as being promises, yet they seem to work well with an async await?
Then, when a load fails, I don't see how to tell that things went wrong. Actually what I don't see is how to tell that things went right!
If I do:
let failed = false;
let newTexture;
try {
newTexture = await PIXI.Texture.from(url);
} catch (err) {
console.log(`FAILED loading texture from ${url}, err=${err}`);
failed = true;
}
console.log(`valid=${texture.valid}`);
Then:
texture.valid is always false, even when the texture loaded and displays just fine
no error is ever thrown when the url points to nowhere
Any pointers, is there a site with good (recent as of 2020) PIXI references? Am I missing something basic? Thanks.
Edit 07/06/2020:
Issues were largely due to both my IDE and webpack not 'seeing' that I had update pixi.js to 5.3.0, restart of both gave me access to Texture.fromURL.
The Texture.from call is a synchronous one. My understanding is that by default, it will load a 'valid' texture of 1x1 px in case of failure. Texture.fromURL was added to provide an async solution, see https://github.com/pixijs/pixi.js/issues/6514
Looks to me like Texture.fromURL still needs a bit of work, as it doesn't seem to ever return on a failed fetch (at least for relative paths, which is what I use). I see the same thing when using the following approach:
const texture = PIXI.Texture.from(url, {
resourceOptions: { autoLoad: false }}
);
await texture.baseTexture.resource.load();
With a bad relative path, the load function never returns in my test environment.
Then, when a load fails, I don't see how to tell that things went wrong. Actually what I don't see is how to tell that things went right! If I do:
...
Then:
texture.valid is always false, even when the texture loaded and displays just fine
no error is ever thrown when the url points to nowhere
Ok, first thing: please use the newest version of PIXI which is now 5.3.0: https://github.com/pixijs/pixi.js/releases/tag/v5.3.0
Texture.fromUrl was added in this PR: https://github.com/pixijs/pixi.js/pull/6687/files . Please read description of this PR: https://github.com/pixijs/pixi.js/pull/6687 - user bigtimebuddy describes 3 ways to load Texture synchronously. From this you should understand why it didnt worked in your code.
Also see: https://gamedev.stackexchange.com/questions/175313/determine-when-a-pixi-texture-is-loaded-to-clone-it
About error handling, catching errors and checking if Texture is "valid": please try running following example (modified version of yours) :
let failed = false;
let newTexture;
try {
newTexture = await PIXI.Texture.fromURL('https://loremflickr.com/100/100');
// to see how failure works comment above line and uncomment line below:
// newTexture = await PIXI.Texture.fromURL('http://not-existing-site-0986756.com/not_existing.jpg');
} catch (err) {
console.log(`FAILED loading texture`);
console.log(err);
failed = true;
}
console.log('failed: ' + (failed ? 'yes' : 'no'));
console.log(`valid=${typeof newTexture !== 'undefined' ? newTexture.valid : 'variable newTexture is undefined'}`);
console.log(newTexture ? newTexture : 'n/a');
And lastly about method not found in IDE:
I would like to use this PIXI.Texture.fromURL method (http://pixijs.download/release/docs/PIXI.Texture.html#.fromURL)
However neither my VS Code environment, nor my compiled source can access this method.
I use PhpStorm (but other IntelliJ editor should be similar - for example: WebStorm) and it finds this method:
/**
* Useful for loading textures via URLs. Use instead of `Texture.from` because
* it does a better job of handling failed URLs more effectively. This also ignores
* `PIXI.settings.STRICT_TEXTURE_CACHE`. Works for Videos, SVGs, Images.
* #param {string} url The remote URL to load.
* #param {object} [options] Optional options to include
* #return {Promise<PIXI.Texture>} A Promise that resolves to a Texture.
*/
Texture.fromURL = function (url, options) {
var resourceOptions = Object.assign({ autoLoad: false }, options === null || options === void 0 ? void 0 : options.resourceOptions);
var texture = Texture.from(url, Object.assign({ resourceOptions: resourceOptions }, options), false);
var resource = texture.baseTexture.resource;
// The texture was already loaded
if (texture.baseTexture.valid) {
return Promise.resolve(texture);
}
// Manually load the texture, this should allow users to handle load errors
return resource.load().then(function () { return Promise.resolve(texture); });
};
Do you use the development build of Pixi, or production one? ( https://github.com/pixijs/pixi.js/releases ).
Update 2020-07-06:
Your comment:
One thing still not clear to me though: when using an approach based on PIXI.Loader, do the sprites using a given texture get automatically refreshed once the texture has been loaded, or is there a manual refresh process required?
If you use "PIXI.Loader" approach then you can set the "load" callback - in which you should have all resources / textures already loaded. See: https://pixijs.download/dev/docs/PIXI.Loader.html
First you define which resources need to be loaded:
// Chainable `add` to enqueue a resource
loader.add('bunny', 'data/bunny.png')
.add('spaceship', 'assets/spritesheet.json');
loader.add('scoreFont', 'assets/score.fnt');
and then you define the callback:
// The `load` method loads the queue of resources, and calls the passed in callback called once all
// resources have loaded.
loader.load((loader, resources) => {
// resources is an object where the key is the name of the resource loaded and the value is the resource object.
// They have a couple default properties:
// - `url`: The URL that the resource was loaded from
// - `error`: The error that happened when trying to load (if any)
// - `data`: The raw data that was loaded
// also may contain other properties based on the middleware that runs.
sprites.bunny = new PIXI.TilingSprite(resources.bunny.texture);
sprites.spaceship = new PIXI.TilingSprite(resources.spaceship.texture);
sprites.scoreFont = new PIXI.TilingSprite(resources.scoreFont.texture);
});
You can try this way and inside this callback you can observe that texture of each resource is valid - for example: resources.bunny.texture.valid - it should be true.
Also, as you see in that doc, you can use other more advanced features like middleware or other callbacks for error handling etc.
In Angular 1.2.0, there is this funny comment:
// IE stupidity! (IE doesn't have apply for some native functions)
It sits on line 9835 in the functionCall function:
functionCall: function(fn, contextGetter) {
var argsFn = [];
if (this.peekToken().text !== ')') {
do {
argsFn.push(this.expression());
} while (this.expect(','));
}
this.consume(')');
var parser = this;
return function(scope, locals) {
var args = [];
var context = contextGetter ? contextGetter(scope, locals) : scope;
for (var i = 0; i < argsFn.length; i++) {
args.push(argsFn[i](scope, locals));
}
var fnPtr = fn(scope, locals, context) || noop;
ensureSafeObject(context, parser.text);
ensureSafeObject(fnPtr, parser.text);
// IE stupidity! (IE doesn't have apply for some native functions)
var v = fnPtr.apply
? fnPtr.apply(context, args)
: fnPtr(args[0], args[1], args[2], args[3], args[4]);
return ensureSafeObject(v, parser.text);
};
},
I believe it is causing me pain, but no errors are thrown so I'm having a hard time seeing exactly what native function it might be trying (and failing) to call apply on. Ever since I implemented $q library to use promises to handle async REST calls, IE9 doesn't even make an attempt to call the services (according to the network tab in dev tools). Instead, the promise is immediately rejected. I tried googling for an answer, and looking at angular's docs on using IE, but I'm getting nowhere.
Has anyone had a similar issue with getting promises to work on IE9 using angular's "q-lite"? Does anyone know what this silly comment is referring to specifically?
I believe I figured it out through a ton of trial and error. It seems the issue, in my case, was that I was using the built-in q library for promises... specifically q.all([]):
$q.all([
firstRequest.$promise,
secondRequest.$promise,
thirdRequest.$promise,
moreRequets.$promise
]).then(function() {
//do stuff
});
While I still have not found out what specific operations the angular code refers to when it says some native functions, I found that the docs for function.apply() have the following caveat:
Note: Most browsers, including Chrome 14 and Internet Explorer 9, still do not accept array-like objects and will throw an exception.
Whatever the specifics, removing my reference to $q.all solved it for me. I hope this helps anyone who has this issue in the future. If someone happens to encounter another case where this IE behavior chokes up angular, perhaps they would be so kind as to comment below or add an answer.
FYI, I am currently at angular 1.2.14.
Following code worked perfectly in Console Application in making request and getting response using HttpWebRequest and WebResponse:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.google.com");
WebResponse response = request.GetResponse();
But the same code when written in GridApp(XAML) template, GetResponse() method gave error:
System.Net.HttpWebRequest Does not contain a definition for 'GetResponse' ...
How come? I included HtmlAgilityPack and all using statements. Does WPF/WindowsStoreApp support slightly different version of GetResponse Method? What am I missing?
In case it is a Windows Store App (and not WPF) there is no synchronous GetResponse method in class WebResponse.
You have to use the asynchronous GetResponseAsync instead, e.g. like this:
using (var response = (HttpWebResponse)(await request.GetResponseAsync()))
{
...
}
If you take a look at the WebRequest page, you'll see that some members are marked with a green icon (a suitcase?). Those are "Supported in .Net for Windows Store apps".
I am trying to get contents of http://www.yahoo.com using WebClient#DownloadStringAsync(). However as Silverlight doesn't allow cross domain calls i am getting TargetInvocationException. I know we have to put clientaccesspolicy.xml and crossdomain.xml in our web server root but that is possible only if i have control on my services. Currently Google is not under my control ;), so how do i handle it?
I've did a workaround by making a WCF service in my web application and then calling WebClient. This works perfectly but it is rather ineffecient. Is there any other better way than this?
Thanks in advance :)
Silverlight's cross domain restricitions cause many developers to implement workarounds. If you need to display the html page you get back you should look into Silverlight 4 (WebBrowser) control although this only seems to work when running out-of-browser mode.
If you need to parse through the content you can try some of the following:
For a managed code solution the proxy service you have already implemented is your best option.
Write a Java applet that returns this information. Silverlight can interopt to javascript which can interopt into Java applets. This also works in the reverse but a little difficult to setup. (If you need more info on this let me know).
Use javascript XmlHttpRequest to get the data you want from the source. This can be difficult when supporting multiple browsers. This link shows an example of how to do this (you will need to scroll down). Javascript get Html
Code:
var xmlHttpRequestHandler = new Object();
var requestObject;
xmlHttpRequestHandler.createXmlHttpRequest = function(){
var XmlHttpRequestObject;
if(typeof XMLHttpRequest != "undefined")
{
XmlHttpRequestObject = new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
var tryPossibleVersions =["MSXML2.XMLHttp.5.0", "MSXML2.XMLHttp.4.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp","Microsoft.XMLHttp"];
for(i=0;i<tryPossibleVersions.length;i++)
{
try
{
XmlHttpRequestObject = new ActiveXObject(tryPossibleVersions[i]);
break;
}
catch(xmlHttpRequestObjectError)
{
// Ignore Exception
}
}
}
return XmlHttpRequestObject;}
function getHtml(){
var url = document.getElementById('url').value;
if(url.length > 0)
{
requestObject = xmlHttpRequestHandler.createXmlHttpRequest();
requestObject.onreadystatechange=onReadyStateChangeResponse;
requestObject.open("Get",url, true);
requestObject.send(null);
}}
function onReadyStateChangeResponse(){
var ready, status;
try
{
ready = requestObject.readyState;
status = requestObject.status;
}
catch(e) {}
if(ready == 4 && status == 200)
{
alert(requestObject.responseText);
}}