I'm trying to display a KMZ file which resides in a folder that is password protected and has a port different from 80. It looks like this:
http://localhost:8080/assets/data/3641
That will return a KMZ file with the valid MIME type, and I can save and open it in Google Earth if I access this link in the browser.
Google Earth's API has the following methods for displaying KMZ/KML:
KmlNetworkLink - you provide the URL of the KMZ/KML and then attach this object to the GE instance
parseKml() - you provide it a KML string, it gives you back a KmlFeature to attach
fetchKml() - you provide it a URL to a KML/KMZ, it attaches it for you
Another handy method is displayKml() from the Google Earth API Utility library, which uses fetchKml()
fetchKml()
My first attempt was to use fetchKml, but this gives no response - it fails silently. I'm surprised this is considered normal behaviour by the plugin (why doesn't it throw an exception, or provide a second callback to handle errors?). This method works fine if I provide it a sample kmz in the form:
http://localhost/somefile.kmz
I believe the issue is the fact that my first URL is password protected - it will redirect to a login screen if no login session is present, and I suspect that the Google Earth plugin doesn't share the same browser session as the browser - so it runs into a login screen and fails because it receives an HTML file instead of a KMZ/KML.
parseKml()
Pressing on undeterred, I made another API method to unzip the KMZ on the server side and return the KML string:
http://localhost:8080/assets/data/unzip/3641
The beauty of this method is that I write my own JavaScript to perform the GET request - it doesn't go through Google Earth, so the login session I have opened is used and the KMZ can be downloaded. The downfall is that KMZs can contain images and music which the KML file can reference. These can't be passed along with the KML string as far as the documentation is concerned.
KmlNetworkLink
My last attempt was to use KmlNetworkLink and KmlLink. This has the same effect as fetchKml - nothing happens.
UPDATE: Also, it will fail when using "https" without a valid certificate.
Yes the issue is that URL is password protected. You can get fetchKml() to give some indication of the error if you use it like so:
google.earth.fetchKml(ge, 'http://localhost:8080/assets/data/3641
', finishFetchKml);
function finishFetchKml(kmlObject) {
// check if the KML was fetched properly
if (kmlObject) {
// add the fetched KML to Earth
currentKmlObject = kmlObject;
} else {
// setTimeout prevents a deadlock in some browsers
setTimeout(function() {
alert('Bad or null KML.');
}, 0);
}
}
Kml is designed to be a free open format - if you wish to use it privately on a secure system then you should look at using the enterprise version of the Google Earth Plugin.
Related
Please tell me how to solve the problem.
The site is on Wordpress, the page has several modals with forms.
They all work well. I need to configure adding an email to the Sendpulse address book, which the user enters into the field.
Installed the sendpulse package via composer: https://github.com/sendpulse/sendpulse-rest-api-php
The situation is this:
In the directory with the theme, there is a functions.php file where there is a form handler, in which you can configure sending letters with requests from forms.
In this file, I added, according to the instructions from github sendpulse, the code for sending an email to the address book:
require '../private/vendor/autoload.php';
use Sendpulse\RestApi\ApiClient;
use Sendpulse\RestApi\Storage\FileStorage;
define('API_USER_ID', 'b7****************************************');
define('API_SECRET', 'e1*************************************');
$SPApiClient = new ApiClient(API_USER_ID, API_SECRET, new FileStorage());
$bookID = '15********';
$emailForSP = ['test6#test.ru'];
$SPApiClient->addEmails($bookID, $emailForSP);
If you just add this piece to the beginning of the file, then it works out and the address is added to the book. But sending letters to mail does not work, an error is thrown: https://hsto.org/webt/v8/qn/le/v8qnled6ibyy-ltp9afwyrjv-2q.jpeg
In the error_log file the line is: https://hsto.org/webt/mk/vo/g0/mkvog03mb7olfji0qrjcsyxktf0.jpeg
Error text from main.js file: https://hsto.org/webt/cd/-n/ry/cd-nryfx06_mvgtglu-t9msp8ga.jpeg
That is, this piece of code somehow affects the processing of the form handler function. In general, I need to trigger sending an email to the book after sending a letter to the mail, but in this case nothing works at all.
I didn't look for the cause of the conflict for a long time. Allocated sending e-mail in the sendpulse into a separate file and added ajax post request to this file. I don’t know why I hadn’t thought of this before.
let emailForSendPulse = $form.find('[name="email"]').val();
$.post('/wp-admin/smth.php', {email: emailForSendPulse}, function(data){
console.log('Form sended');
});
I am trying to get the current URL in an AppMaker app. However, the standard JavaScript ways do not work, ScriptApp is not available in AppMaker, and the objects that are in AppMaker do not return the correct URL (that starts with https://script.google.com).
Thanks for any suggestions.
You can run a backend/serverside script and use Apps Script
ScriptApp.getService().getUrl()
See the doc ScriptApp Documentation
To have an app URL on client side, you can load it during app startup. Firstly, let's create server script that returns app URL:
/**
* Get the URL of the published web app.
*/
function getAppUrl() {
return ScriptApp.getService().getUrl();
}
Open your Project settings and put next code to App startup script section:
loader.suspendLoad();
google.script.run.withSuccessHandler(function(url) {
appUrl = url;
loader.resumeLoad();
}).getAppUrl();
Now you are able to use appUrl everywhere in Client Scripts.
Using this approach you can create initial app config on startup that requires specific data from server.
I am working thru the sample todolist application for the Cordova SDK.
the url is here
https://msdn.microsoft.com/en-us/library/dn832630.aspx
I set up a key on the BING Maps website. I can access the location service sending latitude and longitude thru a standard web browser, pasting in the URL with my key.
However the angular call always fails. What is worse is the error is always blank. no status code no error message. Was thinking it must be CORS.
I have run through the sample and downloaded the code sample and both have the same issue.
For anyone going thru the sample. I have realised today that Angular is evil. They say it is nicely testable javascript with dependancy injection, however it doesn't seem to be too interested in telling you what the error is when you have one, it just fails. Great and noble programming ideas, but without an error message it isn't much good.
Anyhow the fix is that Angular is very strict about json code so the line in services.js for the Bings Maps Service method getAddressFromPosition
it used to work with .get() but this was probably an old version of Angular when the demo was written. I tried using 1.2 but the Ripple emulator didn't like references to browser specific code. So I used the latest 1.3.13 I believe.
This is where to access the Bing location service with the Cordova geolocation coordinates returns Json, but Angular wants them wrapped in JSONP. searching the increasing fragmented web it appeared the error might be CORS no, so a many different people had their JSONP calls in controllers, modules, services, some using $http others $resources. Finally using bits and pieces I got JSONP to work with $resources and to plug it into the $promise the call from the controller requires. I used a static Url with Coordinates I knew worked, so you will have to use the :param angular notation to put those back in. Hope it helps someone.
So change to:
getAddressFromPosition: function (position) {
var resource = $resource(url, {}, {
jsonp_query: {
method: 'JSONP'
}
});
return resource.jsonp_query().$promise.then(function (response) {
return response.resourceSets[0].resources[0].address.formattedAddress;
}, function (error) {
return position.coords.latitude + "," + position.coords.longitude
});
edit:
I put the above in and it worked. However the problem was for some reason, perhaps thru debugging, another instance of the app was deployed on another port in ripple. This then change the app to run on this new port. The initial port was 4400. The problem is that and $http or $resource calls in angular have to go thru this emulator, and the emulator was seeing this as cross domain, unless it is configured to the same port the app is running under.
so Url:
http://localhost:4409/index.html?enableripple=cordova-3.0.0-iPhone5
then in the Settings Div dropdown on the right side, the Proxy Port must also be set to 4409 or else the browser will complain that the $http request is cross-domain, before the emulator actually executes it to query Azure mobile service or Bing maps.
So this was very frustrating. However VS Cordova has definately reduced the amount of bits you have to configure to make hybrid mobile apps, there are still little glitches like this which can trip you up. I assumed it was something with angular, because there was no error messages, but in Chrome in the Dev Tools console that was where the error was, and after some googling it was plain that it was the ripple emulator running on a different port than its proxy was not allowing the call to be forwarded on due to Access-Control-Allow not being set.
to download a console returns the following error:
Frame load interrupted by policy change
Example:
Start Download
Console Preview:
Should I configure something in the Compiler or QWebSettings?
I discovered.
In conventional Webkit browsers, the place to download the console shows how the request canceled, so before turning to "download manager" of the browser the request should be canceled.
solution:
//replace [QWebView] by your WebView
connect([QWebView]->page(), SIGNAL(unsupportedContent(QNetworkReply*)),
this, SLOT(downloadContent(QNetworkReply*)));
...
void [main class]::downloadContent(QNetworkReply *reply){
//Replace "[main class]" by "Class" having the signs used in WebView.
[QWebView]->stop();
//solution: stop loading --replace [QWebView] by your WebView
/*function to donwload*/
}
Edit: hard to tell without a proper backtrace I requested in the comments, but it looks like the warning might actually be harmless.
Original:
That's because the QWebView doesn't know what to do with your app.exe file -- it's not an HTML page or a text/plain document or a supported image, after all. The QWebView class is not a web browser; you apparently want to start a download of some file, but there's no full-blown download manager in that class. You will have to provide your own code for this -- the code will have to ask for a proper location to save it, etc.
You can start with QWebPage::setLinkDelegationPolicy and handle this particular click yourself.
I have a flash video player which requests a flv file from a central server. That server might redirect the request to a server from the user's country if possible, a lot like a CDN.
This video player also reports usage stats. One thing I'd like to report is the true server/location from which the player is streaming the video from. So basically, if it gets redirected I want to know about it.
It seems that you can't extract the url from a URLLoader, you can only keep a copy of the URLRequest that you constructed it with.
I notice that you can listen for HTTP status events, which would include a 302 or similar. But unfortunately, the HTTPStatusEvent object doesn't show the redirected location.
Any ideas about how to monitor for a redirect, and get the redirected location?
I'm a bit surprised Flash allows you to redirect a video request at all. I did a bit of digging and it looks like you can get the info:
Handling Crossdomain.xml and 302 Redirects Using NetStream
His post specifically talks about the trouble of security issues that arise because of the fact some operations fail if data is from an untrusted server. Since he doesn't know where his video is coming from (302 redirect) the Flash Player doesn't trust it and prevents some operations on the loaded content.
How he gets the server the content was actually loaded from is to do an operation on the file that should not be allowed and he parses the domain information from the error message:
try
{
var bit:BitmapData = new BitmapData(progressiveVideoPlayer.measuredWidth, progressiveVideoPlayer.measuredHeight, false, 0x000000);
bit.draw(progressiveVideoPlayer);
}
catch(error:SecurityError)
{
var list:Array = error.toString().split(" ");
var swfURL:String = list[7] as String;
var domain:String = list[10] as String;
domain = domain.substring(0, domain.length - 1);
var domainList:Array = domain.split("/");
var protocol:String = domainList[0] as String;
var address:String = domainList[2];
var policyFileURL:String = protocol + "//" + address + "/crossdomain.xml";
Security.loadPolicyFile(policyFileURL);
}
Notice he is doing it so that he can load the policy file (to allow the security restricted operations on the file). I'm not sure it will be helpful to you but at least read the article and have a think about it. You may contact the blog author directly too - he is pretty active in the general Flash community.