I have a program where i have a page in the local context and within this page i have got an iframe where the content of it is in the web context. Now I would like to send some data from the local context to the web context. How do i do this.
local
var node = document.createElement("iframe");
node.src = 'ms-appx-web:///pages/mapView/mapView.html?latitude=' + coordinates.latitude + '&longitude=' + coordinates.longitude;
node.style.width = '100%';
node.style.height = '100%';
node.onload = function () {
node.contentWindow.postMessage(JSON.stringify(data), "ms-wwa-web://" +
document.location.host);
}
document.querySelector('#insert').appendChild(node);
in the iframe i do:
window.addEventListener('message', receiveMsg, false);
I have got an ajax call where i got some data, but because i have no access to ajax calls in web context i would like to send some data from this here to mapView.html.
The problem is. I would send some values via Get Parameter, but I have too much data for that.
any help?
Try switching this line:
node.contentWindow.postMessage(JSON.stringify(data), "ms-wwa-web://" +
document.location.host);
... to this:
node.contentWindow.postMessage(JSON.stringify(data), "*");
If that works, you should be ok doing that here in a Win 8 app (wouldn't do that in a web app for security reasons), but if you want to lock it down more I think you'd just need to change the second parameter to be one of:
"ms-www-web:///" (note the triple slash)
"ms-www-web:///pages/"
Related
I simply have to access an object that is a variable on the page that I am running my content script on from my Chrome Extension.
I know about the environments and their isolated worlds in which the content scripts and injected scripts run and that it's possible to get some variables using the injected scripts and then send them back.
I have searched for other answers regarding this question and most work for other type of variables and are the basic way of doing it but none currently work for accessing objects.
Any current solutions or workarounds?
EDIT: The solution that I used:
Content script:
//Sends an object from the page to the background page as a string
window.addEventListener("message", function(message) {
if (message.data.from == "myCS") {
chrome.runtime.sendMessage({
siteObject: message.data.prop
});
}
});
var myScript = document.createElement("script");
myScript.innerHTML = 'window.postMessage({from: "myCS", prop: JSON.stringify(OBJECT)},"*");';
document.body.appendChild(myScript);
Background.js:
//Info receiver
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
//When the content script sends the sites object to extract the needed data
if (message.siteObject !== undefined) {
console.log(message.siteObject);
//Process the data
}
});
You can try to inject a script tag in the page to access the object. If needed, you could use messaging to communicate with your extension. For example, assuming the object you want to access in your page is called pageObject:
content1.js
//this code will add a new property to the page's object
var myOwnData = "createdFromContentScript";
var myScript = document.createElement("script");
myScript.innerHTML = "pageObject.myOwnData = " + myOwnData;
document.body.appendChild(myScript);
content2.js
//this code will read a property from the existing object and send it to background page
window.addEventListener("message", function(message) {
if (message.data.from == "myCS") {
chrome.runtime.sendMessage({theProperty: message.data.prop});
}
});
var myScript = document.createElement("script");
myScript.innerHTML = 'window.postMessage({from: "myCS", prop: pageObject.existingProperty},"*");';
document.body.appendChild(myScript);
No, there is no way. There is no point having the isolated worlds for security and then there being a workaround whereby an extension can hack the content script and variables if it really needs to.
Presumably the object on the page interacts with the page or has some effect on the page or something on the page affects the state of the variable. You can trigger actions on the page (via the DOM) that might change the state of that variable but you should stop looking for ways to access variables directly.
Of course if the page author is cooperative then it's a different ball game - a mechanism could be provided in the author's script, a getter and setter mechanism. But somehow I doubt that's what you're after.
Our clients use our free service using code like this:
<script type='text/javascript'>id='example'; width='640'; height='480';</script><script type='text/javascript' src='http://example.com/example.js'></script>
example.js looks like this:
if (typeof (width) == "undefined") {
var width = '100%';
}
if (typeof (height) == "undefined") {
var height = '100%';
}
if (typeof (p) == "undefined") {
var p = '0';
}
if (typeof (c) == "undefined") {
var c = '0';
}
if (typeof (stretching) == "undefined") {
var stretching = 'uniform';
}
document.write('<iframe allowfullscreen width="' + width + '" height="' + height + '" scrolling="no" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" allowtransparency="true" src="http://example.com/examplefile.php?id=' + id + '&p=' + p + '&c=' + c + '&stretching=' + stretching + '"></iframe>');
The problem is people are leeching examplefile.php. We tried using secure_link with nginx, and it worked great, but only for clients who are able to use PHP code in their sites, generating a random secure token with a key. Some other clients can only embed HTML code. Is there a way to secure the examplefile.php or maybe change the examplefile.php name randomly, and verify it against our server to stop the leeching?
Maybe using jQuery? We need to be able to make sure examplefile.php is begin called by this JavaScript code and not added manually as an iframe from external sites.
You could replace the JavaScript with a AJAX request that sends a custom HTTP Request Header with a token. Upon validating the token your server would respond with the URL for use in the iframe. This solution provides you with the opportunity to control the URL so you could randomise it.
An alternative is to send the request to a URL that indicates your intent to access the resource. It could respond with a session cookie which will be carried by the subsequent request for the iframe link.
Here's some vanilla JavaScript to get you started with the AJAX request.
var myURL = 'https://www.example.com/path/',
myCustomKey = 'Custom-Header',
myCustomValue = 'Custom-Token-Value',
myRequest = new XMLHttpRequest();
// open request so that custom header can be added
myRequest.open('GET', myURL, true);
// set custom header for request
myRequest.setRequestHeader(myCustomKey, myCustomValue);
myRequest.onload = function () {
// Request finished. Do processing here.
if (myRequest.status === 200) {
// Request was successful
// use the response
console.log(myRequest.response);
}
};
myRequest.send(null);
You will have to configure the server to support CORS. See https://enable-cors.org/server.html
If I understand correctly, you want to ensure you're the only one using this resource.
One way to do it is to replace example.js with a generated JS file example.php.
This file will have two responsibilities:
Verifying the request against your server
Output plain JS content, as if it were a JS file (with appropriate header data).
Update
This is my approach to be specific:
By using the example.php file (instead of the example.js), each time a user loads the file, initialize a unique session token for the client, in which you will validate immediately in examplefile.php. This way you can make sure (to some level) the request came from example.php
as you know, using the API postMessage of html5, we can post message to an iframe of the current page, or to a new popup window, but if we code like this:
var popwindow = window.open('http://localhost:8080/index2.html');
popwindow.postMessage({"age":10},
'http://localhost:8080/index2.html');
we will not get the message for we use "postMessage" when the popup window has not loaded yet, so how can we make sure the popup window is loaded? we cannot use popwindow.onload in the current page, so how can we? pls help me ~ thanks
you could alwyas use
window.opener.postMessage(...
in index2.html to signal the opener that it is loaded
or, there's the oldschool way:
in index.html
function imOpen(win) {
win.postMessage(// whatever ...
}
window.open('index2.html');
in index2.html
window.addEventListener('load', function() {
window.opener.imOpen(window);
});
You don't need the postMessage API for a popup window being used this way.
//Inside parent window
var data = {age: 10}; //No quotes around age
window.open('http://localhost:8080/index2.html');
//Inside popup window
var sameData = window.opener.data;
Admittedly though, you probably shouldn't use a popup window through window.open(...), since they get blocked all the time.
If you go with an iframe modal, you might be able to get the postMessage way to work by doing something like
//In iframe
window.addEventListener("message", iframeReceiveMessage);
document.addEventListener("DOMContentLoaded", function() {
//JSON data for message
window.parent.postMessage("iframe is ready", "http://localhost:8080");
});
function iframeReceiveMessage(event) {
var iframeData = JSON.parse(event.message);
//iframeData.age === 10
}
and then listening in the parent with:
//In parent
window.addEventListener("message", parentReceiveMessage);
function parentReceiveMessage(event)
{
if (event.origin !== "http://localhost:8080" && event.message !== "iframe is ready") { return; }
var iframe = document.getElementById("iframeId").contentWindow,
parentData = {age: 10};
iframe.postMessage(JSON.stringify(parentData), "http://localhost:8080");
}
Since some browsers only accept strings in the postMessage response so you'd have to convert your data to JSON.
Still, it's probably overkill for sending object data. If you're already on the same domain, have you thought about using sessionStorage?
https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage
You'll still have to use JSON.stringify and JSON.parse (sessionStorage only stores strings), but it's pretty simple:
//Store it
var data = {age: 10};
sessionStorage.data = JSON.stringify(data);
//Use it
var newData = JSON.parse(sessionStorage.data);
//Remove it
sessionStorage.removeItem("data");
One drawback to this method is that sessionStorage is separate for HTTPS pages, so you can't send sessionStorage data between the two protocols!
I am building a Windows Phone 7 hybrid application using PhoneGap.
We are opening a child browser in our application.
The problem is we are not able to send some data to child browser window from our javascript file.We have tried to use local storage but local storage value are not accessible in child browser.
This is the section of code from where we are opening child browser.(parent browser)
$("#openformbtn").click(function(){
ChildBrowser.install();
localStorage.qString='h=NAS1&t=0000927686:1000&n=abc&e=a#g.com&c=776895654568&hname=mnl&cname=Ahm';
var cb = window.plugins.childBrowser;
cb.showWebPage('x-wmapp1://app/www/payment-info.html',false);
});
});
This code is called in child browser when it gets loaded(child browser)
$(document).ready(function(){
createPaymentInfo();
});
function createPaymentInfo(){
var query= localStorage.qString;
}
Append the data to the url.
$("#openformbtn").click(function(){
ChildBrowser.install();
var qString='h=NAS1&t=0000927686:1000&n=abc&e=a#g.com&c=776895654568&hname=mnl&cname=Ahm';
var cb = window.plugins.childBrowser;
var url = 'x-wmapp1://app/www/payment-info.html' + '?' + qString;
cb.showWebPage(url, false);
});
Then inside the child browser you can have some code like:
var params = location.href.split('?')[1];
and parse into an array or whatever from there.
Enviroment: Visual Studio 2012, MVC4, Razor, Internet Application.
I'm working with eBay API and I want to show the search results (JSON).
I have a view page with code...
<script>
function _cb_findItemsByKeywords(root)
{
var items = root.findItemsByKeywordsResponse[0].searchResult[0].item || [];
var html = [];
html.push('<table width="100%" border="0" cellspacing="0" cellpadding="3"><tbody>');
for (var i = 0; i < items.length; ++i)
{
var item = items[i];
var title = item.title;
var pic = item.galleryURL;
var viewitem = item.viewItemURL;
if (null != title && null != viewitem)
{
html.push('<tr><td>' + '<img src="' + pic + '" border="0">' + '</td>' +
'<td>' + title + '</td></tr>');
}
}
html.push('</tbody></table>');
document.getElementById("results").innerHTML = html.join("");
}
</script>
This line in ".js" file:
var url = "http://ebay.com?..."
How can I execute this url from ".js" file automatically, when I openning this View Page? (This url sending request to Ebay server and receiving data, which will be showed on this View Page.)
I will change a question a little...
If I'm running this code from the View page, everything works fine:
<script src=http://ebay.com?... </script>
How can I receive this part("http://ebay.com?..." as a variable) from ".js" file? Is it possible?
If you just want to send the request, you could add an image to the DOM with that as the src, for instance.
If you want to receive data from the request, you're going to have to do an AJAX call. This is handled quite differently in different browsers, so here's a good idea to use a framework, such as jQuery.
Since the URL is on a different domain than yours, however, you won't be able to access it with a regular AJAX request. You'd have to refer to what is called a JSONP request. This requires that the document you're fetched is formatted in a specific manner to allow this. If it isn't, JavaScript simply won't allow this interaction, due to the Same-Origin Policy.
JSONP requires that the remote document has the following format:
someCallbackFunction(javaScriptObjectWithData);
If it does, you'd be able to include a script file to the DOM with that URL as the src, the content of the document, once fetched, will be immediately executed in your browser. You should by then have specified a callback function with a name matching the callback being made in the document (this is usually something you can specify with through querystrings in the original request).
If none of these options are available for you, because of the format of the remote document, then you're going to have to request the document from server side. If you don't have access to a serverside environment yourself, in order to do this, there is the option of using somebody elses server. Yahoo's custom query language – YQL – can be used for querying the content of remote documents, and YQL is available through JSONP, so you could possibly relay your request through them.
See this post on using YQL with JSONP
Update, now that you've added more data, eBay API is available for JSONP, and I think that's the solution you're looking for.
Resolved...
<script src="/Scripts/ebay.js" type="text/javascript"></script>
<script>
s = document.createElement( 'script' );
s.src = url;
document.body.appendChild( s );
</script>