JS Bookmarklet to open PDF-Files in External Viewer? - javascript

I have a program (Mendeley) that tries to open PDF files that are stored locally by accessing the URL: http://path.to/file.pdf (instead of file://path.to/file.pdf). This results in an error in my browser (not unexpected).
What I would like to do is have a javascript bookmarklet that uses the URL in the address bar (which is basically correct besides the http part) and opens the file in an external viewer (Acrobat in my case). My latest creation (inspired by other examples on SO has been):
javascript:var a = (location.pathname);
var b = ('file://schbs02'+a);
window.location = (b);`
This does NOT work; in Chrome (latest version) nothing happens. Is it an inherent limitation of bookmarklets (for security purposes) that they can not open local files or is there something wrong with the code?

Related

Javascript acting differently in inappbrowser vs Chrome - Undefined global variables

My problem is that when I use inappbrowser to open my web page, the main javascript file seems to be ignored, even though it is referenced in the Head of the file that I am opening using ref = cordova.InAppBrowser.open('https://MYURLHERE:8484/home/login', '_self', 'location=yes');
I am using chrome://inspect/#devices to inspect the console and I get errors when hitting buttons.. Anything referenced in the main.js file is undefined.. whereas the actual code for the autocomplete and button seems to be executing.
Please note The url is working fine when viewed in the chrome browser. The javascript files seem to load correctly, and all variables are defined correctly. - It is only when I use inappbrowser that I see issues with undefined variables.
My code (cordova app):
ref = cordova.InAppBrowser.open('https://MYURLHERE:8484/home/login', '_self', 'location=yes');
var myInAppBrowserCallback = function(event) {
console.log(event.url, 'LOADED');
};
ref.addEventListener('loadstart', myInAppBrowserCallback);
//Works fine.
My code (from the actual website I'm trying to view in Inappbrowser):
<script src="/Scripts/commonFunctions.js"></script>
var p = 'Hello';
<script src="/Scripts/loginPage.js"></script>
$('#btnLogin').on('click', function() {
alert(p);
});
Returns an alert with undefined.
What I have tried:
Extensive googling! (all the answers seem to be related to javascript not being enabled.. or 404 errors or things like that.. Not with global variables from one js file being undefined in another js file.)
Removing inappbrowser, using window.open.. Won't work as the app needs to execute scripts to inspect localstorage of the site.
Re-installing the android platform using cordova.
Re-installing the plugin.
Checking chrome in the inspector to ensure the files are in sources tab (they are).
Checking that the functions in main.js also exist (they do).
Thanks, JFIT
Summary:
The problem was that a javascript file was trying to load 'SpeechSynthesis' which was undefined only in the inappbrowser.
Details:
The problem with this was confusing but here are the steps I found to debug / solve:
Set up Remote Debugging on the phone so that you can view the console of the phone using chrome://inspect/#devices
View the console of the inappbrowser site (which will show as a seperate page to the inappbrowser instance.
Identify which files are being loaded and remove files until 'undefined' errors disappear.
Add back in the most recent file and start to strip out various functions (especially functions/variables before document.ready (global variables also)
Find the line/variable that way. It was handy for me this way as the actual undefined variable showed up after I removed most of the files.
The actual cause of my error was the speechSynthesis functionality.
The speechsynthesis lines were removed, and I readded all remaining files and everything works. This function works fine in chrome on desktop/android but not in the inappbrowser.

How do I read a JSON file using HTML?

Here is my code:
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
<script>
$(function() {
var thing = [];
var bar = $.getJSON('C:\Users\cccompro\foo.json', function(obj) {
for (i = 0; i < obj.length; i++) {
thing.push(obj[i]);
}
});
});
</script>
I'm not sure why it doesn't work. "foo.json" contains an array of objects.
If you are trying the code at Question at Chrome or Chromium browsers, launch the browser instance with --allow-file-access-from-files flag set. Note that open instances of Chrome or Chromium should be closed when you launch the browser or the instance will be launched with the open browser instances' configuration folder, instead of with the flag set. You can launch Chrome or Chromium with an existing instance open and honoring the flag by using --user-data-dir flag with value set a different directory than open instance of Chrome or Chromium.
Technically, it is also possible to write to user file system without using an extension with window.webkitRequestFileSystem. Though using chrome.fileSystem within an extension provides an API designed to achieve the read/write.
See
Jquery load() only working in firefox?
Read local XML with JS
How to Write in file (user directory) using JavaScript?
How to use webkitRequestFileSystem at file: protocol
JavaScript/Ajax Write to File
Using <input type="file"> element
How to print all the txt files inside a folder using java script
You cannot read files directly from the users hard drive without the browsers permission. This would be a huge security issue if you could even though there are ways to allow this (checkout guests answer).
You could however try to make the user select the file and then read it with Javascript.
This is called the HTML 5 file API.
However, this doesn't work for any browser and you probably have to use a server anyway in this case.
For more information on this checkout this or this post.

"Access is Denied" when embedding file from blob URL in IE

I have a web service that is sending the client a file as an arraybuffer which is then read into a blob object:
$scope.contentType = response.headers["content-type"];
$scope.file = new Blob([response.data], { type: $scope.contentType });
$scope.fileUrl = URL.createObjectURL($scope.file);
$scope.content = $sce.trustAsResourceUrl($scope.fileUrl);
I am using an object tag as the container:
<object id="documentContainer" ng-show="loaded" ng-attr-type="{{contentType}}" ng-attr-data="{{content}}" class="document-container"></object>
This works great in FF, chrome, mobile browsers, web browsers developed by alien species who have never had contact with humanity, etc., but not in IE.
When the data parameter of the object tag is set, IE responds in the console with
Error: Access is denied.
This seems to be some sort of security feature in IE where it doesn't want to use the file as a source because it resides on the client machine. It prohibits access even if you use javascript to create a brand new dom element with the data source set.
Microsoft provides their own blob methods like msSaveOrOpenBlob, but I need to be able to embed the file in the browser, not prompt the user to open the file in an external application.
Does anyone know of a workaround or way to embed the blob, which can be a wide variety of file types, in IE? I would hate to have to drastically refactor the web service and front end code just to accommodate IE, but it is looking like that might have to be the case.
I think the answer is "no". Our site generates PDF on the fly but we sniff the browser for what can be done with the returned PDF.
Example: http://www.cloudformatter.com/CSS2Pdf.Demos.Structures
If you are on Chrome you could select the "Embed PDF" here and it works like a charm ... if you are on IE, even if you select "Embed", it downloads the file. Because IE cannot and we just reroute anyone on IE to the download code.
http://caniuse.com/#feat=datauri
And don't get us started on what else is wrong on IE, several of the pages just broke because IE stopped serializing end tags for some "p" tags in the document.

How can I spoof the navigator.platform property in Safari? - Safari Extension

I would like to spoof the navigator.platform property in Safari so that I can make websites think that I am running on a Windows architecture. I created a Safari extension that attempts to do this. The plugin simply contains a blank "global.html" file and a file "spoof.js" that is injected as a "start script" (basically it executes on every page before the content of that page loads). The contents of spoof.js are:
//Copied from http://stackoverflow.com/questions/2166540/how-can-i-fool-a-site-that-looks-at-the-javascript-object-navigator-to-see-tha
new_navigator = {};
for (var i in navigator) {
new_navigator[i] = navigator[i];
}
new_navigator.platform = 'Windows';
navigator = new_navigator;
//alert(navigator.platform);
If I uncomment the last line the alert box will say "Windows" every time I load a page, but when I test the extension using this page the website always reads the navigator.platform property as "MacIntel".
I found this excerpt in Apple's Safari extension developer's guide.
Injected scripts have an implied namespace—you don’t have to worry
about your variable or function names conflicting with those of the
website author, nor can a website author call functions in your
extension. In other words, injected scripts and scripts included in
the webpage run in isolated worlds, with no access to each other’s
functions or data.
Does this mean that there is no way that I can edit the navigator item with a Safari extension? Is there any way that I can set the navigator object using an extension?

IE8 blocked this site from downloading files -- javascript window.open location discrepancy

I manage an ASP.NET site where they want to open multiple reports at the click of a button (preferably each in its own tab). The reports are saved as URLs for now, so I just need to open multiple windows with those urls.
I am attempting to do so using javascript (namely window.open). Here is an example of what I am doing (though I removed the actual urls):
<html>
<body>
<button onclick="openLinks();return false;">Open both links</button>
<script type="text/javascript">
function openLinks(){
var FirstWindow = window.open('');
FirstWindow.location = 'https://myssrsReportURL/rs:Format=EXCEL';
window.open('https://myssrsReportURL/rs:Format=EXCEL');
}
</script>
</body>
</html>
The first 2 lines of the js method above has the advantage of forcing the url to open in a new tab versus a new window. However, in the example above, when I set the location after opening a blank window, I receive the file download error IE "blocked this site from downloading":
Where as the second url opens (in a new window) without issue (I get a file download prompt).
Why does the second method work (I receive a file download prompt) while the first doesn't (I receive an IE security warning) if they are opening the same url? Is there some way around this using javascript (or jQuery)?
The customer is requiring that a single button click open all these reports. I can not zip them all up in one request because the reports are generated by SSRS upon a get request to a specific url (the ones I am attempting to open in new tabs).
Note, the question is not, "how do I open multiple tabs" it's why does the behavior discrepancy exist between window.open('') versus window.open('url')
There is no JavaScript magic trick to trick browsers into opening multiple tabs. And if there is...it will be stopped as it is a security vulnerability (download/tabs spam denial of service).
There is a better solution, which works on every browser. You can even choose between JavaScript and ASP.NET.
Create multiple iframe elements and show one at a time by using on-page tabs/links/buttons (simple onclick action to reveal one iframe and hide the rest). For downloads, this method has the advantage of not losing the current page if a server side script fails (so instead of 500 Internal Error or blank page the user remains on the current page).
For multiple downloads, why not zip the files on the server to have a single download prompt? It makes sense to not annoy users with many many download prompts.

Categories

Resources