Detect data URI in links support with Modernizr - modernizr

Using data URI in links (<a href="data:) is not supported in IE and Microsoft Edge (Data URI link <a href="data: doesn't work in Microsoft Edge).
I'm trying to use Modernizr to detect data URI in links support.
Modernizr.datauri is not quite what I'm looking for, as it does not tell anything about support data URI in links, e.g. for Microsoft Edge it returns object {over32kb: true}
How can I detect using Modernizr if data URI in links is supported in browser?

I had the same need for feature detection but I am not using Modernizr. My use case is that I'm generating a pdf on the client side with the makePDF library and was not able to open the PDFs using data URIs in IE or Edge. Unfortuantely, all the feature detection scripts I could find were testing for support of data URIs for images (which is supported by MS browsers) so I had to write my own. Here's the code (thanks to BoltClock's comment above for the idea):
checkDataURISupport(function (checkResult) {
if (checkResult) {
alert('Files in data URIs are supported.');
} else {
alert('Files in data URIs are NOT supported.');
}
})
function checkDataURISupport(callback) {
try {
var request = new XMLHttpRequest();
request.onload = function reqListener() {
callback(true);
};
request.onerror = function reqListener() {
callback(false);
};
request.open('GET', 'data:application/pdf;base64,cw==');
request.send();
} catch (ex) {
callback(false);
}
}
checkDataURISupport()
I tested in in IE 11, Edge 25, Firefox 46, and Chrome 49.
As a side note, another SO answer (https://stackoverflow.com/a/26003382/634650) suggested using:
supportsDataUri = 'download' in document.createElement('a');
This works in IE but not Edge.
Update
The SO answer above also includes a link to a SO answer referencing a Modernizr issue about feature detection for data URI in iframe support. Opening a data URI in an iframe is basically the same thing as opening one in a new windows and the Microsoft browsers which do not support data URIs in iframes don't support opening them in new windows. Additionally, the test for the iframe support mentioned in those locations is synchronous so I would recommend using it instead of my async solution.

It is weird that even Microsoft Edge is not supporting the data URI. Older versions of IE only allows base64 encoded images of up to 32KB. I had come across a reference link lately which relates to the similar issue you have mentioned with Moderinzr.
Does modernizr check for data uri's?#294
It appears they have added a patch for the issue. It is a data URI test.
This post has the similar answer regarding the issue. I hope these fixes should work throughout.

Related

file upload not working on internet explorer 8 and 9

function uploadFile(){
var file = $("file1").files[0];
var formdata = new FormData(); formdata.append("file1", file);
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.addEventListener("error", errorHandler, false);
ajax.addEventListener("abort", abortHandler, false);
ajax.open("POST", "upload.php";
ajax.send(formdata);
}
Error1: Unable to get value of the property '0': object is null or undefined
Error2: ForData not supported.
The FormData API is not supported by IE8 or IE9. It was only added in IE10. If you want to support these old browsers, then you cannot use modern HTML5 APIs.
There is a jQuery Forms plugin which does work in old IE versions and can allow you to upload files via ajax. I've used it myself and it is very effective. You can download it here: http://malsup.com/jquery/form/. You will probably need to rewrite your code a fair bit in order to use it as it's quite different conceptually to the HTML5 FormData API, but at least you'll get something that will work across all the browsers you want to support.
You could also try looking to see if there's a polyfill for FormData which would allow you to keep using your existing code. A quick google turned up this one, which I found listed here. I haven't tried it so can't vouch for it, but the polyfills listed by Modernizr on that list are generally pretty good.

Does Google offer API access to the mobile friendly test?

Is there an API that allows access to Google's Mobile Friendly Test which can be seen at https://www.google.com/webmasters/tools/mobile-friendly/?
If you can't find one by googling, it probably doesn't exist.
A hacky solution would be to create a process with PhantomJS that inputs the url, submits it, and dirty-checks the dom for results.
PhantomJS is a headless WebKit scriptable with a JavaScript API.
However, if you abuse this, there is a chance that google will blacklist your ip address. Light use should be fine. Also be aware that google can change their dom structure or class names at any time, so don't be surprised if your tool suddenly breaks.
Here is some rough, untested code...
var url = 'https://www.google.com/webmasters/tools/mobile-friendly/';
page.open(url, function (status) {
// set the url
document.querySelector('input.jfk-textinput').value = "http://thesite.com";
document.querySelector('form').submit();
// check for results once in a while
setInterval(function(){
var results = getResults(); // TODO create getResults
if(results){
//TODO save the results
phantom.exit();
}
}, 1000);
});
There is an option in pagespeed api
https://www.googleapis.com/pagespeedonline/v3beta1/mobileReady?url={url}&key={api key}
key can be obtained form google cloud platform.
Acquire a PageSpeed Insights API KEY in https://console.developers.google.com/apis/api/pagespeedonline-json.googleapis.com/overview?project=citric-program-395&hl=pt-br&duration=P30D and create a credentials, follow the google's instructions.
In C# (6.0) and .NET 4.5.2, I did some like this:
(add in your project a reference for Newtonsoft.Json.)
String yourURL = "https://www.google.com.br";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://www.googleapis.com");
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var response = client.GetAsync($"/pagespeedonline/v3beta1/mobileReady?url={yourURL }&key=AIzaSyArsacdp79HPFfRZRvXaiLEjCD1LtDm3ww").Result;
string json = response.Content.ReadAsStringAsync().Result;
JObject obj = JObject.Parse(json);
bool isMobileFriendly = obj.Value<JObject>("ruleGroups").Value<JObject>("USABILITY").Value<bool>("pass");
There is an API (Beta) for the Mobile Friendly-Test. (Release Date: 31.01.2017).
The API test outputs has three statuses:
MOBILE_FRIENDLY_TEST_RESULT_UNSPECIFIED Internal error when running this test. Please try running the test again.
MOBILE_FRIENDLY The page is mobile friendly.
3.NOT_MOBILE_FRIENDLY The page is not mobile friendly.
Here are more informations: https://developers.google.com/webmaster-tools/search-console-api/reference/rest/v1/urlTestingTools.mobileFriendlyTest/run

Detect url the user is viewing in chrome/firefox/safari

How can you detect the url that I am browsing in chrome/safari/firefox via cocoa (desktop app)?
As a side but related note, are there any security restrictions when developing a desktop app that the user will be alerted and asked if they want to allow? e.g. if the app accesses their contact information etc.
Looking for a cocoa based solution, not javascript.
I would do this as an extension, and because you would like to target Chrome, Safari, and Firefox, I'd use a cross-browser extension framework like Crossrider.
So go to crossrider.com, set up an account and create a new extension. Then open the background.js file and paste in code like this:
appAPI.ready(function($) {
appAPI.message.addListener({channel: "notifyPageUrl"}, function(msg) {
//Do something, like send an xhr post somewhere
// notifying you of the pageUrl that the user visited.
// The url is contained within msg.pageUrl
});
var opts = { listen: true};
// Note: When defining the callback function, the first parameter is an object that
// contains the page URL, and the second parameter contains the data passed
// to the context of the callback function.
appAPI.webRequest.onBeforeNavigate.addListener(function(details, opaqueData) {
// Where:
// * details.pageUrl is the URL of the tab requesting the page
// * opaqueData is the data passed to the context of the callback function
if(opaqueData.listen){
appAPI.message.toBackground({
msg: details.pageUrl
}, {channel: "notifyPageUrl"});
}
}, opts ); // opts is the opaque parameter that is passed to the callback function
});
Then install the extension! In the example above, nothing is being done with the detected pageUrl that the user is visiting, but you can do whatever you like here - you could send a message to the user, you could restrict access utilizing the cancel or redirectTo return parameters, you could log it locally utilizing the crossrider appAPI.db API or you could send the notification elsewhere, cross-domain, to wherever you like utilizing an XHR request from the background directly.
Hope that helps!
And to answer the question on security issues desktop-side, just note that desktop applications will have the permissions of the user under which they run. So if you are thinking of providing a desktop app that your users will run locally, say something that will detect urls they access by tapping into the network stream using something like winpcap on windows or libpcap on *nix varieties, then just be aware of that - and also that libpcap and friends would have to have access to a network card that can be placed in promiscuous mode in the first place, by the user in question.
the pcap / installed desktop app solutions are pretty invasive - most folks don't want you listening in on literally everything and may actually violate some security policies depending on where your users work - their network administrators may not appreciate you "sniffing", whether that is the actual purpose or not. Security guys can get real spooky so-to-speak on these kinds of topics.
The extension via Crossrider is probably the easiest and least intrusive way of accomplishing your goal if I understand the goal correctly.
One last note, you can get the current tab urls for all tabs using Crossrider's tabs API:
// retrieves the array of tabs
appAPI.tabs.getAllTabs(function(allTabInfo) {
// Display the array
for (var i=0; i<allTabInfo.length; i++) {
console.log(
'tabId: ' + allTabInfo[i].tabId +
' tabUrl: ' + allTabInfo[i].tabUrl
);
}
});
For the tab API, refer to:
http://docs.crossrider.com/#!/api/appAPI.tabs
For the background navigation API:
http://docs.crossrider.com/#!/api/appAPI.webRequest.onBeforeNavigate
And for the messaging:
http://docs.crossrider.com/#!/api/appAPI.message
And for the appAPI.db stuff:
http://docs.crossrider.com/#!/api/appAPI.db
Have you looked into the Scripting Bridge? You could have an app that launches, say, an Applescript which verifies if any of the well known browser is opened and ask them which documents (URL) they are viewing.
Note: It doesn't necessarily need to be an applescript; you can access the Scripting Bridge through cocoa.
It would, however, require the browser to support it. I know Safari supports it but ignore if the others do.
Just as a quick note:
There are ways to do it via AppleScript, and you can easily wrap this code into NSAppleScript calls.
Here's gist with AppleScript commands for Safari and Chrome. Firefox seems to not support AE.
Well obviously this is what I had come across on google.
chrome.tabs.
getSelected
(null,
function
(tab) {
alert
(tab.url);
}) ;
in pure javascript we can use
alert(document.URL);
alert(window.location.href)
function to get current url

Cross-subdomain AJAX works in Chrome, not IE

I have a local build of my site running at local.mydomain.com. I'm making ajax requests to api.mydomain.com which is running on an AWS server and returns JSON. In Chrome, I can call the API no problem. But in IE, I get Access Denied.
After researching, it seems to be a cross-(sub)domain restriction. But I was under the impression that this restriction would apply to both browsers. Can anybody see what might be going wrong here and why it might work in some browsers and not others?
It looks like the problem was in the transport object that IE8+ wants you to use. jQuery uses either ActiveXObject (for IE) or XMLHttpRequest (all others), but IE 8 and above requires XDomainRequest for ajax.
What you can do is return a custom xhr object via $.ajaxSettings.xhr like this,
// override xhr for browser that use XDR
if ('XDomainRequest' in window && window.XDomainRequest !== null) {
// override default jQuery transport
jQuery.ajaxSettings.xhr = function() {
try { return new XDomainRequest(); }
catch(e) {
console.log('test');
}
};
// also, override the support check
jQuery.support.cors = true;
}
I pulled this code from a discussion on the subject here:
http://graphicmaniacs.com/note/getting-a-cross-domain-json-with-jquery-in-internet-explorer-8-and-later/
Definitely take a look at that if you think you're experiencing the same problem.

ActiveX Object is not defined

Firebug is giving me the following error:
ActiveXObject is not defined
[Break on this error] var xmlhttp = new ActiveXObject("MSXML2.XmlHttp");
I've read that ActiveX is a Microsoft framework and its mostly used in IE. All of the internal web pages at the place I work were designed and built specifically for IE 6, but now they want me to research what it would take to move to Firefox and Safari and other major browsers... and ActiveX does not work in Firefox.
So how do I get the ActiveX stuff to work in Firefox and Safari specifically on Mac (for starters)? I know there is a couple of plugins? that have made things easier... like FF ActiveX Host... but is there a programmatic solution to this?
If there is no solution, no plugin, for this problem, is it possible to rewrite the ActiveX pieces in Java?
I’m not a web guy but it seems like your web pages use AJAX.
So your problem is not using AcitveX in other browsers.
Try something like this:
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
xmlhttp = false;
}
}
}
The Plugin-API nearly every relevant browser besides IE supports is the NPAPI, see e.g. this introduction.
I am not aware of any transparent programmatic soutions for adapting ActiveX, especially since its a Windows only technology.
An alternative might be the FireBreath project, which eases working with the NPAPI as well as giving you an abstraction layer over NPAPI and ActiveX - the idea being that you have to write most central parts only once.
Disclaimer: i am one of the owners of the project and thus probably biased ;)

Resources