cordova pushplugin can't get device token in iOS - javascript

I'm trying to add push notifications on cordova/phonegap apps using the pushplugin https://github.com/phonegap-build/PushPlugin
I installed the plugin with
cordova plugin add https://github.com/phonegap-build/PushPlugin.git
It seems it's working because when I run the app for the first time on my device (iPhone 5) it says "your app want send you notifications bla bla..." but then I don't get the device token: it should show an alert by now.
This is how I edited the default index.js created by cordova:
var pushNotification;
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicitly call 'app.receivedEvent(...);'
onDeviceReady: function() {
// app.receivedEvent('deviceready');
// var pushNotification;
$("#app-status-ul").append('<li>deviceready event received</li>');
document.addEventListener("backbutton", function(e)
{
$("#app-status-ul").append('<li>backbutton event received</li>');
if( $("#home").length > 0)
{
// call this to get a new token each time. don't call it to reuse existing token.
//pushNotification.unregister(successHandler, errorHandler);
e.preventDefault();
navigator.app.exitApp();
}
else
{
navigator.app.backHistory();
}
}, false);
try
{
pushNotification = window.plugins.pushNotification;
$("#app-status-ul").append('<li>registering ' + device.platform + '</li>');
if (device.platform == 'android' || device.platform == 'Android' ||
device.platform == 'amazon-fireos' ) {
pushNotification.register(successHandler, errorHandler, {"senderID":"661780372179","ecb":"onNotification"}); // required!
} else {
pushNotification.register(tokenHandler, errorHandler, {"badge":"true","sound":"true","alert":"true","ecb":"onNotificationAPN"}); // required!
}
}
catch(err)
{
txt="There was an error on this page.\n\n";
txt+="Error description: " + err.message + "\n\n";
alert(txt);
}
// handle APNS notifications for iOS
function onNotificationAPN(e) {
if (e.alert) {
$("#app-status-ul").append('<li>push-notification: ' + e.alert + '</li>');
// showing an alert also requires the org.apache.cordova.dialogs plugin
navigator.notification.alert(e.alert);
}
if (e.sound) {
// playing a sound also requires the org.apache.cordova.media plugin
var snd = new Media(e.sound);
snd.play();
}
if (e.badge) {
pushNotification.setApplicationIconBadgeNumber(successHandler, e.badge);
}
}
// handle GCM notifications for Android
function onNotification(e) {
$("#app-status-ul").append('<li>EVENT -> RECEIVED:' + e.event + '</li>');
switch( e.event )
{
case 'registered':
if ( e.regid.length > 0 )
{
$("#app-status-ul").append('<li>REGISTERED -> REGID:' + e.regid + "</li>");
// Your GCM push server needs to know the regID before it can push to this device
// here is where you might want to send it the regID for later use.
console.log("regID = " + e.regid);
}
break;
case 'message':
// if this flag is set, this notification happened while we were in the foreground.
// you might want to play a sound to get the user's attention, throw up a dialog, etc.
if (e.foreground)
{
$("#app-status-ul").append('<li>--INLINE NOTIFICATION--' + '</li>');
// on Android soundname is outside the payload.
// On Amazon FireOS all custom attributes are contained within payload
var soundfile = e.soundname || e.payload.sound;
// if the notification contains a soundname, play it.
// playing a sound also requires the org.apache.cordova.media plugin
var my_media = new Media("/android_asset/www/"+ soundfile);
my_media.play();
}
else
{ // otherwise we were launched because the user touched a notification in the notification tray.
if (e.coldstart)
$("#app-status-ul").append('<li>--COLDSTART NOTIFICATION--' + '</li>');
else
$("#app-status-ul").append('<li>--BACKGROUND NOTIFICATION--' + '</li>');
}
$("#app-status-ul").append('<li>MESSAGE -> MSG: ' + e.payload.message + '</li>');
//android only
$("#app-status-ul").append('<li>MESSAGE -> MSGCNT: ' + e.payload.msgcnt + '</li>');
//amazon-fireos only
$("#app-status-ul").append('<li>MESSAGE -> TIMESTAMP: ' + e.payload.timeStamp + '</li>');
break;
case 'error':
$("#app-status-ul").append('<li>ERROR -> MSG:' + e.msg + '</li>');
break;
default:
$("#app-status-ul").append('<li>EVENT -> Unknown, an event was received and we do not know what it is</li>');
break;
}
}
function tokenHandler (result) {
$("#app-status-ul").append('<li>token: '+ result +'</li>');
// Your iOS push server needs to know the token before it can push to this device
// here is where you might want to send it the token for later use.
alert(result);
}
function successHandler (result) {
$("#app-status-ul").append('<li>success:'+ result +'</li>');
}
function errorHandler (error) {
$("#app-status-ul").append('<li>error:'+ error +'</li>');
}
document.addEventListener('deviceready', onDeviceReady, true);
},
// Update DOM on a Received Event
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
}
};
app.initialize();
In the index.html I didn't make any change... just added the last two .js files like in the example even if the index.html is almost empty
<!DOCTYPE html>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<html>
<head>
<!--
Customize this policy to fit your own app's needs. For more guidance, see:
https://github.com/apache/cordova-plugin-whitelist/blob/master/README.md#content-security-policy
Some notes:
* gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication
* https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
* Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
* Enable inline JS: add 'unsafe-inline' to default-src
-->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<link rel="stylesheet" type="text/css" href="css/index.css">
<title>Hello World</title>
</head>
<body>
<script type="text/javascript">
// var pushNotification;
</script>
<div class="app">
<h1>Apache Cordova</h1>
</div>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript" charset="utf-8" src="js/jquery_1.5.2.min.js"></script>
<script type="text/javascript" src="js/PushNotification.js"></script>
</body>
</html>
I'm not even sure I added the var pushNotification and all the functions in the right places...
I'm very new to phonegap, trying to learn but all the examples I find are very different from the files created when I make a new app.
I also read there are some problems with pushplugin and iOS 8, can't understand if they've been solved or not.
Anyone can give me any suggestion?
Thank you

Your index.js is all fine, you need to fix following things in your index.html:
1: You dont have to inlcude PushNotifications.js on your own, so remove
<script type="text/javascript" src="js/PushNotification.js"></script>,
cordova.js will include automatically all plugins js files.
2: Include script jquery above index.js.
3: In you index.js you have following code
if (device.platform == 'android' || device.platform == 'Android' ||
device.platform == 'amazon-fireos' ) {
This will give you error because device object is not defined, actually it is object which is exported from device plugin,so install this plugin by runnig command
cordova plugin add cordova-plugin-device
4: Also add <ul id="app-status-ul"></ul> in your index.html, so you can see results.
Make these changes and your code will work perfectly.

Related

Why can't I send an XHR request with Cordova?

I'm new to Apache Cordova and i've heard that it's the simplest way to develop android apps. So I did everything okay (or at least I believe so), but I can not get XHR request on my app. Both mobile & TV shows the same thing, while emulators like bluestacks showing the desired result.
What I see (big screen - android tv, small screen - my mobile):
I expect to see whatever my server returns.
This is my code (HTML: <div id="i" style="font-size:20px;line-height:auto;">Please wait while we initialize the app...</div>; index.js on cordova):
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
// Cordova is now initialized. Have fun!
var __domain = 'http://192.168.1.100/android-app/';
var xhr = new XMLHttpRequest();
xhr.open('get', __domain + '.cordova.request.allow.php', 1);
xhr.addEventListener('readystatechange', function() {
document.getElementById('i').innerHTML += '<br>Preparing requested files...';
document.getElementById('i').innerHTML += '<br>ReadyState on ' + this.readyState + ' and Status returned ' + this.status;
if (this.readyState === 4 && this.status === 200 && this.response == 1) {
// It's okay
// Append init
var s = document.createElement('script');
s.src = __domain + 'init.js';
// Force load this script
document.getElementsByTagName('head')[0].appendChild(s);
}
}, 0);
xhr.send();
}
PHP file should return "1" (as string - the file contents: <?php echo 1; return;), and this is init.js:
document.body.style.background = 'blue';
document.body.style.color = 'white';
alert('success');
What am I doing wrong? How can I dynamically get data from server with XHR?
Both mobile & tv connected to the same network using WiFi
(using xiaomi mi box for tv and xiaomi redmi mobile)
Update - for #CedricCholley:
<meta http-equiv="Content-Security-Policy" content="default-src * data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src * 'unsafe-inline'; media-src *; img-src * data: content:;">
Solved with the help of #CedricCholley. I connected the app to chrome console (with the guide here: https://ourcodeworld.com/articles/read/48/how-to-debug-a-cordova-app-on-your-device-with-google-chrome) and got the error Failed to load resource: net::ERR_CACHE_MISS. after googling i've found out that this is happening because the app has no permission to access the internet, so i've followed this guide also: https://cordova.apache.org/docs/en/2.7.0/cordova/connection/connection.html
added the following:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
to platforms\android\app\src\main\AndroidManifest.xml

Can't load source properly unless refresh in debug mode Cordova iOS project

I am trying to initialize a bluetooth central in Cordova iOS project via . a plugin from this github. My code looks like below:
-www
index.js
var app = {
// Application Constructor
initialize: function() {
document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
//initialize the Bluetooth adapter
document.addEventListener('deviceready', function () {
new Promise(function (resolve) {
bluetoothle.initialize(resolve, { request: true, statusReceiver: false });
}).then(initializeSuccess, handleError);
});
},
/* rest part is just the Cordova helloword template*/
};
app.initialize();
/ServiceS/BLEService.js
function initializeSuccess(result) {
if (result.status === "enabled") {
log("Bluetooth is enabled.");
log(result);
}
else {
document.getElementById("start-scan").disabled = true;
log("Bluetooth is not enabled:", "status");
log(result, "status");
}
}
function handleError(error) {
var msg;
if (error.error && error.message) {
var errorItems = [];
if (error.service) {
errorItems.push("service: " + (uuids[error.service] || error.service));
}
if (error.characteristic) {
errorItems.push("characteristic: " + (uuids[error.characteristic] || error.characteristic));
}
msg = "Error on " + error.error + ": " + error.message + (errorItems.length && (" (" + errorItems.join(", ") + ")"));
}
else {
msg = error;
}
log(msg, "error");
if (error.error === "read" && error.service && error.characteristic) {
reportValue(error.service, error.characteristic, "Error: " + error.message);
}
}
function log(msg, level) {
level = level || "log";
if (typeof msg === "object") {
msg = JSON.stringify(msg, null, " ");
}
console.log(msg);
if (level === "status" || level === "error") {
var msgDiv = document.createElement("div");
msgDiv.textContent = msg;
if (level === "error") {
msgDiv.style.color = "red";
}
msgDiv.style.padding = "5px 0";
msgDiv.style.borderBottom = "rgb(192,192,192) solid 1px";
document.getElementById("output").appendChild(msgDiv);
}
}
and index.html
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<link rel="stylesheet" type="text/css" href="css/index.css">
<title>Hello World</title>
</head>
<body>
<div class="app">
<h1>Apache Cordova</h1>
<div id="deviceready" class="blink">
<p class="event listening">Connecting to Device</p>
<p class="event received">Device is Ready</p>
</div>
<p id="output"></p>
</div>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/Services/BLEService.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</body>
</html>
Basically everything here are just the startup code getting from the Cordova helloword and the github of that bluetooth plugin. I tried to build up the project in XCode and everything works fine so far. No error for build and run on device.
Than after I run the project directly on my phone, there is no response whether the initialize success or fail. I do get the message in the Output in xcode indicate "Received Event: deviceready" though. So I think it is just the part of "promise" javascript wasn't work. Than I link the debugger from safari and use the developer tool over there. If I click the refresh manually over there, by the next time the application is reloaded on the phone, I do can see the "Bluetooth is enabled" and {"status": "enabled"} in the output now.
But I have no clue why all the functions in the promise just will not be loaded in the first time. Do anyone have any clue on that?
Alright. I end up this whole thing with actually understand the .m part of this plugin. On the cordova-plugin-bluetoothle github up to 2017/12/11, if you look into the BluetoothLePlugin.m line 664, when you initial the centralManager, the first time you initialize it, it will not return whether enabled or disabled. Only you recalled it a second time, you will be able to see the "enabled" feedback. Therefore, I changed my code in the index.js to following:
document.addEventListener('deviceready', function () {
//the reason following function be called twice is, the plugin is designed like this
//(check BluetoothLePlugin.m line 664 and after)
//first time this function will intialize the centralManager, but will not check whether it is enabled or not
new Promise(function (resolve) {
bluetoothle.initialize(resolve, { request: true, statusReceiver: false });
}).then(initializeSuccess, handleError);
//for the second time it will check if it's enabled or not
new Promise(function (resolve) {
bluetoothle.initialize(resolve, { request: true, statusReceiver: false });
}).then(initializeSuccess, handleError);
});
And it work as I expected after. I am considering to report this interesting "feature" to the author to see if this weird solution is due to my misunderstanding or what.

Phonegap functions not defined in Phonegap build apps - also pushNotifications don't work

I am having trouble to get phonegap working properly. The phonegap function/objects don't seem to be working. Also push notifications don't work too even though I have included the plugin using the proper CLI command and have made sure that all the files are in the correct places according to the documentation. I have use javascript code from the PushNotifications plugin documentation so I assume it is correct also.
I have installed PhoneGap on Mac OS X 10.8.4 and created a new PhoneGap project using the CLI interface.
Then I wrote the HTML/CSS/JavaScript files for the app and placed them in the www directory.
I used the following command to build and run the application on my android device:
phonegap local run android
It worked fine and the application launched on my device. Everything worked fine.
Then I added some code that uses phonegap's functions/objects and tried to run it on android again.
The app ran fine again, but this time the following code did not execute:
alert(device.platform);
Also the PushNotifications code did not execute too due to an error (device is not defined)
I have tried to include cordova.js, phonegap.js, both of them at the same time or even none of them, but the result is still same.
I checked to see if the platforms/android/assets/www folder in the project directory contained the correct files, and it did. Both cordova.js and phonegap.js files were automatically added (phonegap build command adds both files for backward compatibility reasons, at least thats how I understood it).
So I am trying to figure out why device object is undefined even when phonegap.js file exists in the www folder and is included in the html file. I think if I can get the "alert(device.platform);" code working then the push notification code would work too, as it fails at the if statement that has to evaluate device.platform.
Here is the code for the index page:
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="css/index.css"/>
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8" src="js/jquery-2.0.0.min.js"></script>
<script type="text/javascript" charset="utf-8" src="js/functions.js"></script>
<script src="js/fastclick.js"></script>
<script type="text/javascript" src="PushNotification.js"></script>
<script type="text/javascript" src="http://debug.build.phonegap.com/target/target-script-min.js#f997ffa0-5ed6-11e2-84ec-12313d1744da"></script>
<script type="text/javascript" charset="utf-8">
//*********************************************************
// Wait for Cordova to Load
//*********************************************************
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
//THE FOLLOWING CODE IS RESPONSIBLE FOR PUSH NOTIFICATIONS
var pushNotification;
alert(device.platform);
try {
pushNotification = window.plugins.pushNotification;
if (device.platform == 'android' || device.platform == 'Android') {
$("#app-status-ul").append('<li>registering android</li>');
pushNotification.register(successHandler, errorHandler, {"senderID":"hidden-by-me","ecb":"onNotificationGCM"}); // required!
} else {
$("#app-status-ul").append('<li>registering iOS</li>');
pushNotification.register(tokenHandler, errorHandler, {"badge":"true","sound":"true","alert":"true","ecb":"onNotificationAPN"}); // required!
}
}
catch(err) {
txt="There was an error on this page.\n\n";
txt+="Error description: " + err.message + "\n\n";
alert(txt);
}
//Rest of the code
updateData();
if (window.localStorage.getItem("default-school") == "infant") {
window.location.replace("infant.html");
} else
if (window.localStorage.getItem("default-school") == "junior") {
window.location.replace("junior.html");
};
}
// iOS
function onNotificationAPN(event) {
if (event.alert) {
navigator.notification.alert(event.alert);
}
if (event.sound) {
var snd = new Media(event.sound);
snd.play();
}
if (event.badge) {
pushNotification.setApplicationIconBadgeNumber(successHandler, errorHandler, event.badge);
}
}
// Android
function onNotificationGCM(e) {
$("#app-status-ul").append('<li>EVENT -> RECEIVED:' + e.event + '</li>');
switch( e.event ) {
case 'registered':
if ( e.regid.length > 0 ) {
$("#app-status-ul").append('<li>REGISTERED -> REGID:' + e.regid + "</li>");
// Your GCM push server needs to know the regID before it can push to this device
// here is where you might want to send it the regID for later use.
console.log("regID = " + e.regID);
}
break;
case 'message':
// if this flag is set, this notification happened while we were in the foreground.
// you might want to play a sound to get the user's attention, throw up a dialog, etc.
if (e.foreground) {
$("#app-status-ul").append('<li>--INLINE NOTIFICATION--' + '</li>');
// if the notification contains a soundname, play it.
var my_media = new Media("/android_asset/www/"+e.soundname);
my_media.play();
}
else {
// otherwise we were launched because the user touched a notification in the notification tray.
if (e.coldstart) $("#app-status-ul").append('<li>--COLDSTART NOTIFICATION--' + '</li>');
else $("#app-status-ul").append('<li>--BACKGROUND NOTIFICATION--' + '</li>');
}
$("#app-status-ul").append('<li>MESSAGE -> MSG: ' + e.payload.message + '</li>');
$("#app-status-ul").append('<li>MESSAGE -> MSGCNT: ' + e.payload.msgcnt + '</li>');
break;
case 'error':
$("#app-status-ul").append('<li>ERROR -> MSG:' + e.msg + '</li>');
break;
default:
$("#app-status-ul").append('<li>EVENT -> Unknown, an event was received and we do not know what it is</li>');
break;
}
}
function tokenHandler (result) {
$("#app-status-ul").append('<li>token: '+ result +'</li>');
// Your iOS push server needs to know the token before it can push to this device
// here is where you might want to send it the token for later use.
}
function successHandler (result) {
$("#app-status-ul").append('<li>success:'+ result +'</li>');
}
function errorHandler (error) {
$("#app-status-ul").append('<li>error:'+ error +'</li>');
}
</script>
</head>
<body onload="initFastButtons();init();">
<span id="fastclick">
<div id="main">
<ul id="app-status-ul">
<li>Push Plugin test</li>
</ul>
</div>
</span>
</body>
</html>
It would be really great if anyone could help me out on this one.
Which version of phonegap are you using?
If v3 then did you install the 'device' plugin?
$ phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git
I was attempting to get this working in Phonegap Build for a long time and finally figured it out:
config.xml
<gap:plugin name="org.apache.cordova.device" /> <!-- Needed to use device.model (Not available until document deviceready event-->
javascript:
function deviceReady() {
alert(device.model);
}
document.addEventListener("deviceready", deviceReady, false);
However, I found out this object is not needed for the information i was looking for (device.model and device.version) because it was available in navigator.userAgent.
The version is the Android version number in the useragent string and the device model is right after "Android" in the useragent string.

Capture audio and upload it

I'm working on mobile device (iOS). I develop a hybrid application using HTML/CSS/Javascript.
I have this code founded on Apache Cordova API :
<!DOCTYPE html>
<html>
<head>
<title>Capture Audio</title>
<script type="text/javascript" charset="utf-8" src="cordova-2.5.0.js"></script>
<script type="text/javascript" charset="utf-8" src="json2.js"></script>
<script type="text/javascript" charset="utf-8">
// Called when capture operation is finished
//
function captureSuccess(mediaFiles) {
var i, len;
for (i = 0, len = mediaFiles.length; i < len; i += 1) {
uploadFile(mediaFiles[i]);
}
}
// Called if something bad happens.
//
function captureError(error) {
var msg = 'An error occurred during capture: ' + error.code;
navigator.notification.alert(msg, null, 'Uh oh!');
}
// A button will call this function
//
function captureAudio() {
// Launch device audio recording application,
// allowing user to capture up to 2 audio clips
navigator.device.capture.captureAudio(captureSuccess, captureError, {limit: 2});
}
// Upload files to server
function uploadFile(mediaFile) {
var ft = new FileTransfer(),
path = mediaFile.fullPath,
name = mediaFile.name;
ft.upload(path,
"http://my.domain.com/upload.php",
function(result) {
console.log('Upload success: ' + result.responseCode);
console.log(result.bytesSent + ' bytes sent');
},
function(error) {
console.log('Error uploading file ' + path + ': ' + error.code);
},
{ fileName: name });
}
</script>
</head>
<body>
<button onclick="captureAudio();">Capture Audio</button> <br>
</body>
</html>
I can capture my voice with it and in theory upload it to
http://my.domain.com/upload.php
But I wonder how to adapt this code to upload file on my Dropbox . Is it possible to upload file to Dropbox as easy as that ?
As #sinaneker mentioned, you can do this server-side with PHP (or other languages).
But you can also do this directly from JavaScript using Dropbox's JavaScript library: https://github.com/dropbox/dropbox-js

How to use JavaScript to access cross domain iFrame content?

I would like to use this code
window.parent.document.getElementById('message').value += "\r\n\r\n[img]"+response+"[/img]";
It works fine for pages coming from the same domain, but not for sites from another domain loaded in the iFrame. How can I do it?
You can implement window.postMessage to communicate accross iframes/windows across domains.
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title></title>
<!--
<link rel="shortcut icon" href="/favicon.ico">
<link rel="start" href="http://benalman.com/" title="Home">
<link rel="stylesheet" type="text/css" href="/code/php/multi_file.php?m=benalman_css">
<script type="text/javascript" src="/js/mt.js"></script>
-->
<script type="text/javascript">
// What browsers support the window.postMessage call now?
// IE8 does not allow postMessage across windows/tabs
// FF3+, IE8+, Chrome, Safari(5?), Opera10+
function SendMessage()
{
var win = document.getElementById("ifrmChild").contentWindow;
// http://robertnyman.com/2010/03/18/postmessage-in-html5-to-send-messages-between-windows-and-iframes/
// http://stackoverflow.com/questions/16072902/dom-exception-12-for-window-postmessage
// Specify origin. Should be a domain or a wildcard "*"
if (win == null || !window['postMessage'])
alert("oh crap");
else
win.postMessage("hello", "*");
//alert("lol");
}
function ReceiveMessage(evt) {
var message;
//if (evt.origin !== "http://robertnyman.com")
if (false) {
message = 'You ("' + evt.origin + '") are not worthy';
}
else {
message = 'I got "' + evt.data + '" from "' + evt.origin + '"';
}
var ta = document.getElementById("taRecvMessage");
if (ta == null)
alert(message);
else
document.getElementById("taRecvMessage").innerHTML = message;
//evt.source.postMessage("thanks, got it ;)", event.origin);
} // End Function ReceiveMessage
if (!window['postMessage'])
alert("oh crap");
else {
if (window.addEventListener) {
//alert("standards-compliant");
// For standards-compliant web browsers (ie9+)
window.addEventListener("message", ReceiveMessage, false);
}
else {
//alert("not standards-compliant (ie8)");
window.attachEvent("onmessage", ReceiveMessage);
}
}
</script>
</head>
<body>
<iframe id="ifrmChild" src="child.htm" frameborder="0" width="500" height="200" ></iframe>
<br />
<input type="button" value="Test" onclick="SendMessage();" />
</body>
</html>
Child.htm
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title></title>
<!--
<link rel="shortcut icon" href="/favicon.ico">
<link rel="start" href="http://benalman.com/" title="Home">
<link rel="stylesheet" type="text/css" href="/code/php/multi_file.php?m=benalman_css">
<script type="text/javascript" src="/js/mt.js"></script>
-->
<script type="text/javascript">
/*
// Opera 9 supports document.postMessage()
// document is wrong
window.addEventListener("message", function (e) {
//document.getElementById("test").textContent = ;
alert(
e.domain + " said: " + e.data
);
}, false);
*/
// https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage
// http://ejohn.org/blog/cross-window-messaging/
// http://benalman.com/projects/jquery-postmessage-plugin/
// http://benalman.com/code/projects/jquery-postmessage/docs/files/jquery-ba-postmessage-js.html
// .data – A string holding the message passed from the other window.
// .domain (origin?) – The domain name of the window that sent the message.
// .uri – The full URI for the window that sent the message.
// .source – A reference to the window object of the window that sent the message.
function ReceiveMessage(evt) {
var message;
//if (evt.origin !== "http://robertnyman.com")
if(false)
{
message = 'You ("' + evt.origin + '") are not worthy';
}
else
{
message = 'I got "' + evt.data + '" from "' + evt.origin + '"';
}
//alert(evt.source.location.href)
var ta = document.getElementById("taRecvMessage");
if(ta == null)
alert(message);
else
document.getElementById("taRecvMessage").innerHTML = message;
// http://javascript.info/tutorial/cross-window-messaging-with-postmessage
//evt.source.postMessage("thanks, got it", evt.origin);
evt.source.postMessage("thanks, got it", "*");
} // End Function ReceiveMessage
if (!window['postMessage'])
alert("oh crap");
else {
if (window.addEventListener) {
//alert("standards-compliant");
// For standards-compliant web browsers (ie9+)
window.addEventListener("message", ReceiveMessage, false);
}
else {
//alert("not standards-compliant (ie8)");
window.attachEvent("onmessage", ReceiveMessage);
}
}
</script>
</head>
<body style="background-color: gray;">
<h1>Test</h1>
<textarea id="taRecvMessage" rows="20" cols="20" ></textarea>
</body>
</html>
You can if your browser have disabled security, for chrome it's
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security
Update: I'm surprised that people keep devoting it because they consider it harmful, so here I add some additional details for peoples who don't know basics of web security and still try to develop for it.
DON'T use this solution if
you are using chrome plugins or apps which are not trusted by you, or
you have opened other sites in the chrome, or
you have some malicious chrome processes
your site is using any external resources.
To make this solution completely safe, configure your firewall to block all connections except one to which you are making CORS connection.
Also, don't use this solution if your connection endpoint isn't trusted.
Take a look at easyXDM, it's an easy to use library that provides a unified API for several tricks used to enable cross domain messaging, ranging from postMessage to the FIM-trick as a last resort.
This is what is used by major services such as Twitter and Disqus.
Due to same origin policy restrictions this is not allowed.
As stated, this falls under same origin policy, but there are some tricks that allow limited communication with the iframe. Take a look at http://ajaxify.com/run/crossframe/
You can't. This is called the same origin policy, and prevents javascript accessing content across domains.

Categories

Resources