Embedding Google Maps IFRAME - asp.net-mvc

I can't seem to get this to work, while I have been doing so in the past, succesfully...
I'm trying to embed a Google Maps iframe in a web page. The iframe won't load, showing an error message, saying:
Chrome, in console: Refused to display document because display forbidden by X-Frame-Options.
IE9, on the page: This content cannot be displayed in a frame
The steps I take are:
Go to google maps in the browser
Go the place I want to have embedded
Click the link icon
Copy paste the link that's presented under the label 'Paste HTML to embed in website'.
I'm using ASP.NET MVC4, running locally in IIS Express, but the same happens on the server in IIS7.
Strangely enough, when I just create a local HTML file and open that from the filesystem, I don't have the problem.
When pasting the code in jsfiddle, it does seem to work.
Do I need to configure IIS or add something to my headers, or anything like that?
The HTML snippet
<iframe width="425" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://maps.google.be/maps?f=q&source=s_q&hl=en&geocode=&q=Kortrijk,+Belgium&aq=0&oq=kortrijk,+bel&sll=50.802805,3.279785&sspn=0.351067,0.617294&t=h&ie=UTF8&hq=&hnear=Kortrijk,+West+Flanders,+Vlaams+Gewest&ll=50.802897,3.280106&spn=0.350496,0.617294&z=11&iwloc=A&output=embed"></iframe>

Thanks to the sharp and insightful eye of a colleague of mine, we have found the issue.
First of all it only seems to appear on the Belgian maps, http://maps.google.be, (afaik, obviously), and not on the http://maps.google.com.
When calling the IFRAME content, google redirects the IFRAME content to the same URL, but with ?wmode=transparent appended.
The browser does not allow multiple '?' in a url, so it aborts the action.
To fix:
Use the same URL as generated by Google Maps, but just append the following:
&wmode=transparent

Do you definitely have the &output=embed querystring parameter in the iframe source? If you don't include that then Google won't send the correct X-Frame-Options response headers and you get the error you've described.
Can you show the snippet of the MVC view where the map is being rendered?

I couldn't get any of the various suggestions around the web to work for embedding a google map link in an iframe.
I ended up using the google map API, generating the initial code by filling in the boxes at:
http://www.map-embed.com/
and modifying the resultant code to suit my purposes.
You could use the link above to gen the code for your own map, and then optionally use my code with the longitude and latitude produced by the above web site copied into my code. You can also insert your own html into "content" below, independent of what the above website produces.
<?php
// IE won't work with percentage height and FF won't work with em units.
// Simple code here assumes if browser isn't IE, then is FF;
// And I don't care about other browsers.
//
$height = "$browser" == 'ie' ? '25em' : '99%' ;
$width = "$browser" == 'ie' ? '99%' : '99%' ;
echo <<<XXXEODXXX
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"> </script>
<div style="height:$height; width:$width; overflow:hidden;">
<div id="gmap_canvas" style="height:$height; width:$width;">
</div>
<style>
#gmap_canvas
img
{
max-width:none!important;
background:none!important
}
</style>
</div>
<script type="text/javascript">
google.maps.event.addDomListener ( window, 'load', init_map );
function init_map ()
{ var myOptions = { zoom:12, center:new google.maps.LatLng ( 41.1889495, -104.1781593 ), mapTypeId:google.maps.MapTypeId.ROADMAP };
map = new google.maps.Map ( document.getElementById ( "gmap_canvas" ), myOptions );
marker = new google.maps.Marker ( {map: map, position: new google.maps.LatLng( 41.1889495, -104.1781593 ) } );
infowindow = new google.maps.InfoWindow ( { content:"<b>Biz Name</b><br/>Biz Street Address<br/>Biz City, State Zip<br/>Biz Phone" } );
google.maps.event.addListener ( marker, "click", function () { infowindow.open ( map, marker ); } );
infowindow.open ( map, marker );
}
</script>
XXXEODXXX;
?>

Related

IOS10 above system, mixed content,background-image inserted picture does not display

IOS10 above system, mixed content(html by https,img by http), when the call of geolocation.getCurrentPosition, background-image inserted picture does not display
<pre>
<div id="aaa" style="background-image:url(http://xxx.jpg);height:200px;"></div>
<script>
navigator.geolocation.getCurrentPosition(function (res) {
console.log(res);
});
</script>
</pre>
It is correct behaviour. On https page all http content must not be shown as it is insecure. Even if it is inserted through JS. Browser simply doesn't make request for such content.

Redirect a webbrowser if chrome 18 is not found

I created this script to hide a page only if chrome 18 has not been found, how can I make sure to do the redirect of the url to a external page if chrome 18 has not been found instead of hiding only the page ?
I want to do the redirect to this website http://search.aol.com/aol/webhome
<div id="hiddenContent" style="display: none;">
My hidden content.
</div>
<script>
function GetChromeVersion() {
var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
return raw ? parseInt(raw[2], 10) : false;
}
if (GetChromeVersion() == 18)
document.getElementById("hiddenContent").style.display = "";
</script>
It's possible, e.g. by using:
window.location.href='http://search.aol.com/aol/webhome';
Inside your function. BUT I wouldn't recommend you this. You should never trust the client as JavaScript can easily be changed and someone could access your site even despite the JavaScript redirect if they wanted to and made a minimal effort to modify page sources. Javascript is handled on the client-side, while php is completely server-side. In this case I'd use php instead of JavaScript. Try to check it with php and if it's not chrome 18, use: header('Location: http://search.aol.com/aol/webhome');
Edit:
<?php function is_chrome()
{
return(eregi("chrome/18", $_SERVER['HTTP_USER_AGENT'])); }   if(is_chrome()) { header('Location: http://www.search.aol.com/aol/webhome'); } ?>
Place it on top of the file, should work, but haven't tested it yet, if not, just change the string in eregi('chrome/18') to what you need (it's a regular expression)

Embedded timeline widget not working in SPA

and thanks for taking a moment,
I have gone to the twitter site and created an embedded timeline per their instructions.
if I place the generated code on a simple html page on my desktop, all works as expected. When I place the same code inside my SPA application, i only get a 'follow me' link on the site. The SPA application is built on the John Papa example.
There are no javascript errors thrown. I'm guessing that the heart of the issue may have something to do with the routing, b/c if I navigate directly to the page where I've embedded my timeline, the code works as expected.
i.e. http://localhost:50000/App/views/shared/pillar.html
However, I also have a google calendar widget, and that works as expected.
Tested this in Chrome, FF, IE. Behavior is the same.
Any thoughts on how I might diagnose this further? Or is my approach totally wrong? I'm just looking to add the latest n-number of tweets to what is basically a blog. Nothing too fancy.
<a class="twitter-timeline" href="https://twitter.com/PoundingCode" data-widget-id="313336765203218432">Tweets by #PoundingCode</a>
<script>!function(d,s,id){
var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);
js.id=id;js.src=p+"://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js,fjs);}}
(document,"script","twitter-wjs");
I figured out a solution, but rather than take this down, I hope it might help the next person:
Put the twitter widget code into a new html document.
Have that document take in a querystring called handle
Have that html document parse the querystring and inject it.
Create an iframe bound to an observable that has your twitter handle, passing in that handle as your querystring parameter.
the iFrame data-binding:
iframe data-bind="with: twitter, attr: { src: '../App/views/shared/twitter.html?handle=' + twitter() }" style="height:622px;" seamless="seamless"
The twitter page
<body>
<a class="twitter-timeline" href="https://twitter.com/" + get('handle') data-widget-id="313336765203218432" ></a>
<script>
function get(name) {
if (name = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(location.search))
return decodeURIComponent(name[1]);
}
!function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0], p = /^http:/.test(d.location) ? 'http' : 'https';
if (!d.getElementById(id)) {
js = d.createElement(s); js.id = id;
js.src = p + "://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
}
}(document, "script", "twitter-wjs");</script>
</body>
The Twitter script only checks the DOM once after being loaded. An SPA changes the DOM dynamically, so you have to tell the Twitter script to scan the DOM again:
const twttr = window.twttr
twttr.widgets.load()
If the script was loaded already (usually https://platform.twitter.com/widgets.js), then the twttr object is available in the global namespace.
Here is the relevant documentation: https://developer.twitter.com/en/docs/twitter-for-websites/javascript-api/guides/scripting-loading-and-initialization

Exoclick adult ads on mobile website with JQuery Mobile

I'm having an issue using Exoclick adult advertisement to advertise on a mobile website using JQuery UI.
I don't know how much I can disclose here until it goes too far into "adult" that I can't post it here anymore.
The Exoclick banners show, but only once! Navigating inside the site doesn't the same ad again (we have two ads, bottom and top. Each is only loaded ONCE per site traversal). If you refresh using the refresh function of the browser ("F5"), they will load again... But only once.
Alright, Exoclick gives me a snippet like this:
<!-- BEGIN ExoClick.com Ad Code -->
<script type="text/javascript" src="http://syndication.exoclick.com/ads.php?type=300x50&login=<username>&cat=110&search=&ad_title_color=0000cc&bgcolor=FFFFFF&border=0&border_color=000000&font=&block_keywords=&ad_text_color=000000&ad_durl_color=008000&adult=0&sub=&text_only=0&show_thumb=&idzone=<zone id>&idsite=<site id>"></script>
<noscript>Your browser does not support JavaScript. Update it for a better user experience.</noscript>
<!-- END ExoClick.com Ad Code --></div>
The thing is, this works perfectly on static sites, but due to the nature of JQuery Mobile to fetch everything using AJAX, the scripts would be loaded many times over into the browser's execution context (at least this is what I suppose happens!) and in the end... not even execute anymore?
What I already thought of:
Cache the output of the Exoclick ad script (is there something like "outputcache" for JS?)
Deactivate Ajax
I tried deactivating Ajax requests but for some reason this didn't do anything:
<script>
$(document).bind("mobileinit", function(){
$.mobile.ajaxEnabled = false;
});
</script>
Deactivating Ajax should work:
$(document).bind("mobileinit", function () {
$.mobile.addBackBtn = false;
$.mobile.ajaxEnabled = false;
$.mobile.ajaxLinksEnabled = false;
});
On the other hand, you can refresh/reload your script on each ajax success
$('html').ajaxSuccess(function() {
//reload your script using js, plenty of that on google
});
I did it... #bobek indirectly brought me to this answer.
What I did is create an invisible div which contains the ads at first. Then, on pageinit, I steal the div and remove it from DOM. The div will now have an iframe inside made by Exoclick.
Then, without the script by exoclick, I insert it back into the dom on each page init event...
To prevent that the script gets inserted back into the dom, on the server side I check for the X-REQUESTED-WITH header. If it's XMLHttpRquest, I don't send the ads.
This is how it looks in code:
The temporary ad placement, ANYWHERE on the site:
<div id="ads">
<div style="display: none" id="topad">
<?php require("./_topbannerb.php"); ?>
</div>
<div style="display: none" id="bottomad">
<?php require("./_bottombannerb.php"); ?>
</div>
</div>
The two PHP files contain the tags by exoclick. Nothing else.
A script in the head tag:
<script>
ads = "";
first = true;
$(document).bind('pageinit', function() {
if (first) {
ads = $("#ads");
ads.remove();
}
first = false;
$.each($(".adt"), function(i, v) {
$(v).append($(ads).children("#topad").first().children("div").clone())
});
$.each($(".adb"), function(i, v) {
$(v).append($(ads).children("#bottomad").first().children("div").clone())
});
});
</script>
Then, where the ads are supposed to be placed in the end:
<div class="adt"> </div>
The script automatically inserts into each ad placement. Here I have two different ad regions: Top and bottom. Both have no differences except how exoclick handles them in the back.

jQuery Mobile is not reloading my page properly

Ok, this is odd:
First I open page1.html. From page1.html I go to page2.html by link and then back to page1.html via another link. These links are just regular links with relative path and not rel="back" kind of link.
Problem is: jQuery Mobile will cache page1.html (though it doesn't cache page2.html)
If I add rel="external" to the link of page2.html then the page1 is refresh, but together, all resources is also reloaded (which not what I want).
I only want the html of page1.html to be reloaded. I added data-cache=false and data-dom-cache=false to page1.html annotation but it doesn't help.
How can I have jQuery Mobile not caching page1.html with the given scenario?
I am using a workarround that manualy removes the page based on the data-dom-cache attribute. You need to add an event handler for pagehide events and check for the domCache property of the page data
$(document).on('pagehide', function(event, ui){
var page = $(event.target);
var pageData = page.data(); // get all the data attributes (remove the data prefix and format to camel case)
if(pageData.domCache == false){
console.log("Removing Page (id: " + page.attr('id') + ", url: " + pageData.url + ")"); //Log to console for debugging
page.remove(); // remove the page
}
});

Resources