I'm trying to pass data from Flash to Javascript via ExternalInterface.
It works fine when I'm testing on my localhost, but when I tried to set a website at IIS, so my coworkers could test my application, like: http://192.168.0.10/MyApp, I getting this error:
Error calling method on NPObject.
After reading some questions at Stackoverflow I tried to set allowScriptAccess="always" at my embed tags and Security.allowDomain(*) at my AS file, but it still doesn't work.
I'm using swf object if that matters.
What am I missing?
EDIT: The error occurs when I try to call a method from js to my swf. This is the code adapted to the answer bellow.
var swfReady = false;
swfobject.embedSWF("swf/1.swf", "flashContent", "300", "250", "11", "expressInstall.swf", null, { allowScriptAccess: "always" } , null, function (e) {
if (e.success) {
setTimeout(function () {
swfReady = true;
}, 150);
}
});
btnConfig.on('click', function () {
if (swfReady) {
flashContent.myMethod();
} else {
alert("Hold on...");
}
});
This works great at localhost but when someone try to view the same page through my IP, I get the Javascript error Error calling method on NPObject.
Sometimes this happens when the swf is not ready. You can try the callback function in embedSWF. Don't invoke any swf method until this callback. In addition to this sometimes you will need a few milliseconds of delay.
swfobject.embedSWF("sample.swf", "swfdiv", "400", "300", "9.0.0", "expressInstall.swf", null, null, null, function (e) {
if (e.success) {
console.log("swf ready ");
setTimeout(function(){
// call swf method here
}, 150);
} else {
console.log("embedding failed");
}
});
Related
While integrating Paytm JS Checkout in asp.net C# application it is working fine in google chrome but in mozilla firefox payment popup window does not open and it gives the following error in mozilla console :
"Uncaught TypeError: window.Paytm.CheckoutJS.init is not a function"
<div id="paytm-checkoutjs"></div>
<script type="application/html" crossorigin="anonymous" src="https://securegw-stage.paytm.in/merchantpgpui/checkoutjs/merchants/demoKey.js" onload="onScriptLoad();"> </script>
<script>
function onScriptLoad(){
var config = {
"root": "",
"flow": "DEFAULT",
"data": {
"orderId": "", /* update order id */
"token": "", /* update token value */
"tokenType": "TXN_TOKEN",
"amount": "" /* update amount */
},
"handler": {
"notifyMerchant": function(eventName,data){
console.log("notifyMerchant handler function called");
console.log("eventName => ",eventName);
console.log("data => ",data);
}
}
};
if(window.Paytm && window.Paytm.CheckoutJS){
window.Paytm.CheckoutJS.onLoad(function excecuteAfterCompleteLoad() {
// initialze configuration using init method
window.Paytm.CheckoutJS.init(config).then(function onSuccess() {
// after successfully updating configuration, invoke JS Checkout
window.Paytm.CheckoutJS.invoke();
}).catch(function onError(error){
console.log("error => ",error);
});
});
}
}
</script>
Please help
Thanks
// Wrap inside onLoad and it will work fine.
if (window.Paytm && window.Paytm.CheckoutJS) {
window.Paytm.CheckoutJS.onLoad(function excecuteAfterCompleteLoad() {
// initialze configuration using init method
window.Paytm.CheckoutJS.init(config)
.then(function onSuccess() {
// after successfully updating configuration, invoke JS Checkout
window.Paytm.CheckoutJS.invoke();
})
.catch(function onError(error) {
console.log("error => ", error);
});
});
}
Please once clear your browser cache and cookies, if the issue still persists please raise a query on Paytm Developer Support
Lately i have discovered chrome coverage report that I find very useful.
https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage
The weakness of this tools is that it is single page scoped. But in version chrome 73 there is an option to generate json file for page that can be stored for further processing.
I would like to collect json data for multiple pages, than merge it and visualize in the context of single file (in my case stylesheet).
It would be great if I could receive json file directly through chrome (Extenstion?) API. So far i have found only this example: https://gist.github.com/krisselden/2487706bcbf37da26d4a89d0f74df768. But it seems to work only for browser remote mode.
Do you know is there any way to get coverage json report over chrome API?
Best regards
It Man.
Heres what i got so far (snippets only):
Got extension template form https://extensionizr.com
Inside background.js script have placed this raw method:
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
console.log(request.command);
if (request.command === "getCoverage") {
chrome.tabs.query(
{currentWindow: true, active : true},
function(tabArray){
var activeTab = tabArray[0];
console.log("tabid: " + activeTab.id)
chrome.debugger.attach( { tabId: activeTab.id }, "1.2", function() {
console.log("attached");
chrome.debugger.sendCommand( { tabId: activeTab.id }, "Profiler.enable", undefined, function(result) {
console.log("ProfilerStarted:" ,result);
chrome.debugger.sendCommand( { tabId: activeTab.id }, "Profiler.startPreciseCoverage", { callCount: true }, function(result) {
console.log("coverageStarted:" ,result);
setTimeout(function() {
chrome.debugger.sendCommand( { tabId: activeTab.id }, "Profiler.takePreciseCoverage", undefined, function(response) {
console.log(response.result);
});
}, 4000)
});
});
});
}
);
}
});
Inside browser_action.js:
document.getElementById("getCoverageSnapshot").addEventListener("click", function() {
chrome.extension.sendMessage({
command: "getCoverage"
});
});
And in browse_action.html:
<!doctype html>
<style type="text/css">
</style>
<button id="getCoverageSnapshot">Get Snapshot</button>
<script type="text/javascript" src="/src/browser_action/browser_action.js"></script>
When button clicked Profiler.takePreciseCoverage result can be recieved inside background.js.
Still looking the way to receive css coverage data...
I am using this example Recorder.js Demo for recording audios. It's working fine in Linux, but when I use it on Windows. It gives the alert "Error getting audio", For this code is as below
function initAudio() {
//Some code
navigator.getUserMedia(
{
"audio": {
"mandatory": {
"googEchoCancellation": "false",
"googAutoGainControl": "false",
"googNoiseSuppression": "false",
"googHighpassFilter": "false"
},
"optional": []
},
}, gotStream, function(e) {
console.log("In gotStream function :" +e);
alert('Error getting audio');
console.log(e);
});
}
Any thoughts on this?
I have resolved my problem. The problem is that Chrome has recently changed to require secure origins for all powerful APIs, in particular getUserMedia. I have to run this on https://host not on http://host, otherwise getUserMedia will be failed.
So I'm trying to capture web audio from a tab and pass it into another script that works with DOM elements on the page.
EXTENSION SCRIPT
In the background.js, I use the following script:
chrome.tabCapture.capture(constraints, function(stream) {
console.log("\ngot stream");
console.log(stream);
chrome.tabs.sendMessage(tabID, {
"message": "stream",
"stream": stream
});
});
The Developer Toolkit shows me that the created object is indeed a MediaStream object. (Which I want and appears to be working fine).
EXTENSION CONSOLE:
MediaStream {onremovetrack: null, onaddtrack: null, onended: null, ended: false, id: "c0jm4lYJus3XCwQgesUGT9lpyPQiWlGKHb7q"…}
CONTENT SCRIPT
I use a content script (injected), on the page itself to then pull the JSON serialized object back out:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.message === "stream") {
var thisStream = request.stream;
console.log(thisStream);
if (!thisStream) {
console.log("stream is null");
return;
}
loadStream(thisStream);
}
else if (request.message === "statusChanged") {
console.log("statusChanged");
}
});
PAGE CONSOLE
Unfortunately, because of JSON serialization, the object type is lost:
Object {onremovetrack: null, onaddtrack: null, onended: null, ended: false, id: "c0jm4lYJus3XCwQgesUGT9lpyPQiWlGKHb7q"…}
I need the object recast as a MediaStream object and have tried the following things which all failed:
Attempt 1: FAILED
var stream = new webkitMediaStream;
function loadStream(thisStream) {
stream = thisStream;
}
Attempt 2: FAILED
var stream;
function loadStream(thisStream) {
stream = new webkitMediaStream(thisStream);
}
Attempt 3: FAILED
var stream;
function loadStream(thisStream) {
stream = Object.create(webkitMediaStream, thisStream);
}
NOTE:
The constructor for the MediaStream object IS webkitMediaStream.
I need either a better method for passing the object from the extension script (the only place the chrome.tab.capture() method works from) to the content script (the only place that has access to and can modify the DOM elements of the page),
OR
I need a way of recasting the JSON serialized object back into a fully functional MediaStream object.
Thanks in advance!
JRad the Bad
Extension messages are always JSON-serialized, so it's indeed obvious that you cannot send a MediaStream from the background page to the web page. The question is, do you really need to send the MediaStream from the background to the content script?
If you only need to, e.g. display the video, then you can use URL.createObjectURL to get a blob:-URL for the stream and assign it to video.src to see a video. The URL created by URL.createObjectURL can only be used by a page at the same origin, so you need to create the <video> tag in a chrome-extension:// page; either in a tab, or in a frame. If you want to do this in a frame, make sure that the page is listed in web_accessible_resources.
If you DO really need a MediaStream object of the tab in the tab, then RTCPeerConnection can be used to send the stream. This WebRTC API is normally used to exchange media streams between peers in a network, but it can also be used to send streams from one page to another page in another tab or browser.
Here's a full example. Visit any web page, and click on the extension button. Then the extension will insert a video in the page showing the current tab.
background.js
function sendStreamToTab(tabId, stream) {
var pc = new webkitRTCPeerConnection({iceServers:[]});
pc.addStream(stream);
pc.createOffer(function(offer) {
pc.setLocalDescription(offer, function() {
// Use chrome.tabs.connect instead of sendMessage
// to make sure that the lifetime of the stream
// is tied to the lifetime of the consumer (tab).
var port = chrome.tabs.connect(tabId, {name: 'tabCaptureSDP'});
port.onDisconnect.addListener(function() {
stopStream(stream);
});
port.onMessage.addListener(function(sdp) {
pc.setRemoteDescription(new RTCSessionDescription(sdp));
});
port.postMessage(pc.localDescription);
});
});
}
function stopStream(stream) {
var tracks = this.getTracks();
for (var i = 0; i < tracks.length; ++i) {
tracks[i].stop();
}
}
function captureTab(tabId) {
// Note: this method must be invoked by the user as defined
// in https://crbug.com/489258, e.g. chrome.browserAction.onClicked.
chrome.tabCapture.capture({
audio: true,
video: true,
audioConstraints: {
mandatory: {
chromeMediaSource: 'tab',
},
},
videoConstraints: {
mandatory: {
chromeMediaSource: 'tab',
},
},
}, function(stream) {
if (!stream) {
alert('Stream creation failed: ' + chrome.runtime.lastError.message);
}
chrome.tabs.executeScript(tabId, {file: 'contentscript.js'}, function() {
if (chrome.runtime.lastError) {
stopStream(stream);
alert('Script injection failed:' + chrome.runtime.lastError.message);
} else {
sendStreamToTab(tabId, stream);
}
});
});
}
chrome.browserAction.onClicked.addListener(function(tab) {
captureTab(tab.id);
});
contentscript.js
function onReceiveStream(stream) {
// Just to show that we can receive streams:
var video = document.createElement('video');
video.style.border = '1px solid black';
video.src = URL.createObjectURL(stream);
document.body.insertBefore(video, document.body.firstChild);
}
function onReceiveOfferSDP(sdp, sendResponse) {
var pc = new webkitRTCPeerConnection({iceServers:[]});
pc.onaddstream = function(event) {
onReceiveStream(event.stream);
};
pc.setRemoteDescription(new RTCSessionDescription(sdp), function() {
pc.createAnswer(function(answer) {
pc.setLocalDescription(answer);
sendResponse(pc.localDescription);
});
});
}
// Run once to prevent the message from being handled twice when
// executeScript is called multiple times.
if (!window.hasRun) {
window.hasRun = 1;
chrome.runtime.onConnect.addListener(function(port) {
if (port.name === 'tabCaptureSDP') {
port.onMessage.addListener(function(remoteDescription) {
onReceiveOfferSDP(remoteDescription, function(sdp) {
port.postMessage(sdp);
});
});
}
});
}
manifest.json
{
"name": "tabCapture to tab",
"version": "1",
"manifest_version": 2,
"background": {
"scripts": ["background.js"],
"persistent": false
},
"browser_action": {
"default_title": "Capture tab"
},
"permissions": [
"activeTab",
"tabCapture"
]
}
I have an MVC 5 view with a form and a plupload file uploader section. Upload is triggered by a button on the form. I have no problem uploading file chunks to the server and setting the parameters to the query string and all, but what I do have a problem with is starting the upload only after a custom sanity check has been performed.
Here's what I have tried:
var uploader = new plupload.Uploader({
runtimes: 'html5',
drop_element: 'upload',
browse_button: 'browse',
url: "../UploadFile",
chunk_size: "1024kb",
multipart_params: { "uid": "uid", "chunk": "chunk", "chunks": "chunks", "name": "name" },
init: {
PostInit: function(file) {
document.getElementById("filelist").innerHTML = "";
document.getElementById('submit-all').onclick = function () {
document.getElementById("infoPopup").style.visibility = "visible";
document.getElementById('submit-all').enabled = false;
var uuid = Math.uuidFast();
document.getElementById("uid").value = uuid;
uploader.settings.multipart_params = { uid: uuid, chunk: file.chunk, chunks: file.chunks, name: file.name };
if (checkReq) {
uploader.start();
}
return false;
};
},
The crucial part here is this:
if(checkReq){
uploader.start();
}
"checkReq" is my custom sanity check script that verifies that form values are not nonsensical (e.g. single form entries might be perfectly valid while in combination they are simply wrong, etc.).
So the above does not prevent the upload, the check script is not even fired, Firebug console output shows no error.
Since googling tells me that there is also a "BeforeUpload" event, I tried this:
BeforeUpload: function(up, file) {
if (checkReq) {
up.stop();
return false;
}
return true;
},
Which also does not seem to fire at all.
Edit: Next attempt, I put the call to my checkReq fuction into BeforeUpload in "preinit", which should fire before any chunking etc is done, so before the upload is prepared. This also failed although I have no idea why it does not fire:
var uploader = new plupload.Uploader({
runtimes: 'html5',
drop_element: 'upload',
browse_button: 'browse',
url: "../UploadFile",
chunk_size: "1024kb",
multipart_params: { "uid": "uid", "chunk": "chunk", "chunks": "chunks", "name": "name" },
preinit: {
BeforeUpload: function (up) {
if (checkReq) {
uploader.stop();
uploader.splice(0, uploader.files.length);
return false;
}
return true;
}
},
init: {
PostInit: function(file) {
...
I had used "dropzone.js" before, and my script worked fine with that but I found that I needed chunked uploads so I had to move to plupload and now my script is being ignored.
Could someone please tell me where I am being stupid here? Thanks!
Got it solved.
It's a nasty, ugly hack, but it works:
Made the "actual" submit/upload button hidden
Made a second button that acts as pre-submit button with onclick function
onclick function calls checkReq and if that returns true, the function calls the click() function of the "actual" submit/upload button
Like I said: nasty but it works.