I have a Qt application that embeds a web browser (QWebEngineView). I would like to call a javascript function with a string argument from the C++ application. The means of doing this is calling
page()->runJavaScript("setContent(\"hello\");");
This works in simple cases. However, if I try and load, say, a C++ source file and use that as the parameter of setContent, this will break, because I can't simply assemble the string like this:
auto js = QString("setContent(\"%1\");").arg(fileStr);
I tried the following:
fileStr = fileStr.replace('"', "\\\"");
fileStr = fileStr.replace("\n", "\\n");
But apparently this could not escape the string, I get an error when I call this javascript. How can I universally escape a long string with newlines and possible special characters so that I can construct a valid js fragment like this?
So, after some research, I came across QWebChannel which is meant for bi-directional communication between the application and the hosted webpage. The imported qwebchannel.js in the examples can be found here. From there, this is what I did:
In C++:
auto channel = new QWebChannel(this);
page()->setWebChannel(channel);
channel->registerObject("doc", Doc);
In HTML/JS:
new QWebChannel(qt.webChannelTransport,
function(channel) {
var doc = channel.objects.doc; // this is "doc" from the registerObject call
editor.setValue(doc.text);
doc.textChanged.connect(updateText); // textChanged is a signal of the class of doc.
}
);
So, even though this does not directly answer the question, what is presented here can be used to achieve the same effect.
In the script: `http://theip.com/something/index.php
I have the following javascript URI:
var uri = '/something/script.php?=' + someDynamicValue
That I pass to a function "loadHTML(url, div)"
someDynamicValue can contain spaces and other symbols which make JQuery crash with $.load().
So, I try to encode uri:
$('#'+div).load(encodeURIComponent(uri));
And gives
http://theip.com/something/%2Fsomething%2Fscript.php%3Fq%3D?_=1399924421585
That is, duplicating the /something (which should be an absolute URL so it should go to http://ip.com/something/script.php)
Now if I do the following:
$('#'+div).load(encodeURIComponent(uri).replace(/%2F/g,'/'));
I get a "good" url but gives 404 Error:
http://theip.com/something/script.php%3Fq%3D?_=1399923477529
So I guess it is taking script.php%3Fq%3D?_=1399923477529 as a literal script name, maybe.
How can I fix it? (Encode the rest of the URL).
Thanks!
You just need to encode the one part that isn't already properly URI encoded:
var uri = '/something/script.php?foo=' + encodeURIComponent(someDynamicValue)
$('#'+div).load(uri);
I have a page which redirects to a url from parameters in query string like:
page.html?redirectUrl=index.html
Inside the page i have code like this:
window.localtion.href = redirectUrl;
It is requiements to use redirect url by parameters. The page contains secure sensitive data. Someone can make the url with javascript like:
page.html?redirectUrl=javascript:alert(document.getElementById("password").value)
and secure data can be stolen.
How to prevent bypass javascript code to window.localtion.href?
You might try putting the URL in an anchor element and checking the protocol:
var anchor = document.createElement("a");
anchor.href = redirectUrl;
if(anchor.protocol != "javascript:") {
window.localtion.href = redirectUrl;
}
However, I'm not sure how good the browser support is for this, since MDN lists it as an HTML5 feature.
This seems like it would work as long as you're not redirecting with it:
Javascript:
var field = document.getElementById("redirectUrl");
var newValue = String(field.value);
alert(newValue);
Basically, using the String constructor to "sanitize" the input.
These will probably help more with other cases:
https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet
https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet
Overall, I would recommend NOT using Javascript to sanitize input. If you're handling really sensitive or important data you are highly recommended to use a server-side language to validate and sanitize your input.
Can anybody explain how the following javascript variables:
document.referrer
document.location.href
or the http REFERRER header, could come to be 'javascript:window["contents"]' ?
Not only do I not understand how they could be set to a javascript uri - but window.contents isn't a standard DOM attribute in any browser that I know of... (It is window["contents"], not window["content"])
I believe I found the solution to this..
There are some javascripts in the wild which seem to create iframes using code (something) like this:
var contents = '<html>......</html>';
var ifr = document.createElement('iframe');
ifr.contentWindow.open();
ifr.contentWindow.write(contents);
some particular combination of this sometimes ends up specifying either the href of the iframe , or the referrer, as "javascript:window['contents']" - i.e. the javascript variable which temporarily holds the page data.
(still not completely finalized on the details, but that's the basic idea)
Question:
IE and Firefox / Safari seem to deal differently with BASE HREF and Javascript window.location type requests. First, is this an accurate description of the problem? What's going on? And what's the best cross-browser solution to deal with this situation?
Context:
I have a small PHP flat file sitelet (it's actually a usability testing prototype).
I dynamically generate the BASE tag's HREF value in PHP, i.e. if it's running on our company's server, it's:
$basehref = 'http://www.example.com/alpha/bravo/UsabilityTest/';
and on my local dev machine, it's:
$basehref = 'http://ellen.local/delta/echo/foxtrot/UsabilityTest/';
For one of the tasks, I collect some user input, do some transformations on it in Javascript, and send to the server using code like this:
function allDone() {
// elided code for simplicity of stackoverflow question
var URI = "ProcessUserInput.php?";
URI = URI + "alphakeys=" + encodeURI( keys.join(",") );
URI = URI + "&sortedvalues=" + encodeURI( values.join(",") );
window.location = URI;
}
Both the javascript file (containing function allDone()) and the processing PHP script (ProcessUserInput.php) live in a subdirectory of UsabilityTest. In other words, their actual URL is
http://www.example.com/alpha/bravo/UsabilityTest/foxtrot/ProcessUserInput.php
aka
$basehref . '/foxtrot/ProcessUserInput.php'
The Problem
IE's JavaScript basically seems to ignore the BASE HREF. The javascript and the PHP processor live in the same directory, so the call to ProcessUserInput.php works out fine. The input gets processed and everything works fine.
But when I test on Firefox, the JavaScript does appear to use the BASE HREF, because the script's output gets sent to
$basehref . '/ProcessUserInput.php'
This breaks, because ProcessUserInput.php is in a subdirectory of basehref. However, if I add the subdirectory name to the javascript, it no longer works in IE.
Solutions?
I can think of a few ways to solve this:
In Javascript, read the HREF property of the BASE tag and manually prepend to var URI in the javascript, calling a fully-resolved absolute URL
Process the .js file with PHP and insert the $basehref variable into the script
Move the files around
Something else?
I'm sure there must be other ways to solve this too. What's the best way to deal with BASE HREF in JavaScript when IE and Firefox apply it differently in JavaScript?
Using the assign method of window.location seems like the most straightforward answer.
Instead of
window.location = URI;
I'm using this:
window.location.assign( URI );
which is doing the right thing in both IE and Firefox.
IE and Firefox / Safari seem to deal differently with BASE HREF and Javascript window.location type requests.
Yes, this is a long-standing difference going back to the early days of Netscape-vs-IE.
IE enforces base-href only at the point a document element is interacted-with. So, you can createElement('a'), set a relative href and click() it*, but the base-href will be ignored; appendChild it to the document containing the base-href, and it'll work.
On the other browsers the base-href is taken as global per-window and always applied. Which is right? It seems to be unspecified. The original JavaScript docs say only that location.hash (and hence, location applied as a string):
represents a complete URL
So setting it to a relative URL would seem to be an undefined operation.
(*: link.click() is a non-standard method supported by IE and Opera)
read the HREF property of the BASE tag and manually prepend
Probably what I'd do, yeah, if you're dead set on using <base>.
I believe you want to modify window.location.pathname, not window.location. window.location is a Location object, that has multiple variables. As a result, the effects of changing it is not well defined. However, window.location.pathname is defined as the path relative to the host, which is what you want.
If you want to read up more on the many variables you can change in window.location, I'd check here. According to Mozilla's documentation, changing any variable in window.location should reload the page with a new URL corresponding to those changes.
I had the same problem today, after some researching, couldn´t findn any way to override this issue in IE9, what is a requiremente for my project, so, i did the following approach (jquery based, but it´s really easy to make it in simple javascript).
href = function(url){
if ($("base").length > 0 ){
location.href= $("base").attr("href")+url;
}else{
location.href = url;
}
}
And then, change
location.href= 'emp/start'
to
href('emp/start');
just add $('base').attr('href') before the link. (using jquery) or
document.getElementBytagname('base').href
You can always use Vanilla JS :)
var href = document.getElementBytagname('base')[0].href
I hope this helps.