How to download xlsx, pdf, ppt file with javascript in IE - javascript

In my webpage, I want to download file(ppt, pdf, xlsx) when I click <a/> tag.
I used a tag with download attribute, but in IE it doesn't work.
So I referred to here (Download attribute on A tag not working in IE
), and now download works in IE but the file is not opened. I tried .xlsx file and when I open it, it says that
contents have problem.
How can I download and open my .xlsx .pdf .ppt file in IE with javascript?
I'm a beginner web programmer and I need some advice from a good developer like you.
Thanks in advance.
this is my code
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<a id='a1' href="https://image.shutterstock.com/image-photo/colorful-flower-on-dark-tropical-260nw-721703848.jpg"
download>excel</a>
<script>
function MS_bindDownload(el) {
if (el === undefined) {
throw Error('I need element parameter.');
}
if (el.href === '') {
throw Error('The element has no href value.');
}
var filename = el.getAttribute('download');
console.log("filename : " ,filename);
if (filename === null){
throw Error('I need download property.');
}
if (filename === '') {
var tmp = el.href.split('/');
filename = tmp[tmp.length - 1];
}
el.addEventListener('click', function (evt) {
evt.preventDefault();
var xhr = new XMLHttpRequest();
xhr.onloadstart = function () {
xhr.responseType = 'blob';
};
xhr.onload = function () {
navigator.msSaveBlob(xhr.response, filename);
};
xhr.open("GET", el.href, true);
xhr.send();
})
}
let element = document.querySelector('a');
MS_bindDownload(element);
</script>
</body>
</html>

Related

Loading Worker from worker.js failed beacuse of disallowed MIME type (“text/html”)

I am trying to implement a simple Web Worker.
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
The following is my index.html snippet :
<!DOCTYPE html>
<html>
<head>
<title>Worker</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta content="X-Content-Type-Options=nosniff" http-equiv="Content-Type" />
<link rel="stylesheet" href="css/uikit.min.css" />
<link rel="stylesheet" href="css/font-awesome.min.css">
<script src="js/index.js"></script>
</head>
The follwing is my index.js (Main javascript file) :
var liveWorker;
function spawnLiveWorker()
{
console.log("inside spawnLiveWorker()");
if (typeof(Worker) !== "undefined")
{
if (typeof(liveWorker) == "undefined")
{
liveWorker = new Worker('worker.js');
}
}
else
{
console.error("Sorry, your browser does not support Web Workers...");
}
}
$(document).ready(function() {
console.log("document ready");
spawnLiveWorker();
});
The following is my worker.js :
var curURL = "http://172.30.206.80:8080/dp1_30";
var curAttrib = "2435";
function updateLiveDataWorker()
{
console.log("inside updateLiveDataWorker() in worker");
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function()
{
if (this.readyState == 4 && this.status == 200)
{
console.log("response type in updateLiveDataWorker = ",typeof this.response);
console.log("response in updateLiveDataWorker = ",this.response);
//console.log("")
postMessage(this.response)
}
else
{
console.log("error");
}
}
xhr.open("GET", "/api/device/getTimeSeriesDataForLastUpdatedDay");
xhr.setRequestHeader("Authorization", "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJha3NoYXQuc3JpdmFzdGF2YUBtZGx6LmNvbSIsImV4cCI6MTYzNzU3ODg2OSwiaWF0IjoxNjM3NTYwODY5fQ.dUTJ7hm5xnJhBubDKB2F7-Ob2S83hlYmygrhVDFyuWQSmCWJ31vY_laksE0iP0nbyU2Pz2p578mjibCB3PIRUA");
xhr.setRequestHeader("attributeId", curAttrib);
xhr.send();
}
function startUpdatingLiveDataWorker()
{
console.log("inside startUpdatingLiveDataWorker() in worker");
setInterval(updateLiveDataWorker,30000);
}
updateLiveDataWorker();
startUpdatingLiveDataWorker();
However, I am getting this error :
GEThttp://172.30.206.80/worker/worker.js
[HTTP/1.1 404 1ms]
Loading Worker from “http://172.30.206.80/worker/worker.js” was blocked because of a disallowed MIME type (“text/html”).
I have tried adding the following line as meta tag in index.html :
following instructions from the following page :
X-Content-Type-Options

Why is this HTML code typed in URL bar as 'data:text/html' not working?

I have this html code (below), which works perfectly as a hosted file (meaning the code is working) -
<!DOCTYPE html>
<html>
<head>
<title>Read Text File</title>
<!--<script src="https://thunkable.github.io/webviewer-extension/thunkableWebviewerExtension.js" type="text/javascript"></script>-->
<script>
var ThunkableWebviewerExtension = (function () {
const postMessageToWebview = (message) => {
if (window.ReactNativeWebView) {
window.ReactNativeWebView.postMessage(message);
} else {
window.parent.postMessage(message, '*');
}
};
const getReceiveMessageCallback = (fxn, hasReturnValue) => (event) => {
if (typeof fxn === 'function') {
if (event.data) {
let dataObject;
try {
dataObject = JSON.parse(event.data);
} catch (e) {
// message is not valid json
}
if (dataObject && dataObject.type === 'ThunkablePostMessage' && hasReturnValue) {
fxn(dataObject.message, (returnValue) => {
const returnMessageObject = { type: 'ThunkablePostMessageReturnValue', uuid: dataObject.uuid, returnValue };
postMessageToWebview(JSON.stringify(returnMessageObject));
});
} else if (!hasReturnValue && (!dataObject || dataObject.type !== 'ThunkablePostMessage')) {
fxn(event.data);
}
}
}
};
return {
postMessage: postMessageToWebview,
receiveMessage: function(fxn) {
const callbackFunction = getReceiveMessageCallback(fxn, false);
document.addEventListener('message', callbackFunction, false);
window.addEventListener('message', callbackFunction, false);
},
receiveMessageWithReturnValue: function(fxn) {
const callbackFunction = getReceiveMessageCallback(fxn, true);
document.addEventListener('message', callbackFunction, false);
window.addEventListener('message', callbackFunction, false);
},
};
})();
</script>
</head>
<body>
<input type="file" name="inputfile" id="inputfile">
<br>
<pre id="output"></pre>
<script type="text/javascript">
document.getElementById('inputfile')
.addEventListener('change', function() {
var fr=new FileReader();
fr.onload=function(){
//document.getElementById('output').textContent=fr.result;
var msg = fr.result;
ThunkableWebviewerExtension.postMessage(msg);
}
fr.readAsText(this.files[0]);
})
</script>
</body>
</html>
What I want to do is, turn this whole code into a long URL, and I found that by using 'data:text/html,<meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>' at the start, then adding the code.
So the HTML url would become something like - 'data:text/html,<meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"/><!DOCTYPE html><html><head> ...'
I can see the file upload button, and even can select and upload a file. But, the script parts are not working - I am unable to catch the error here 😪
Kindly guide/advice me here... Thanks!
After experimenting a little bit, I think the problem might be that you haven't url-encoded it. Try using this instead of just pasting in the whole thing directly
(or copy it from here)
data:text/html,%3C!DOCTYPE%20html%3E%0A%3Chtml%3E%0A%3Chead%3E%0A%20%20%20%20%3Ctitle%3ERead%20Text%20File%3C/title%3E%0A%20%20%20%20%3C!--%3Cscript%20src=%22https://thunkable.github.io/webviewer-extension/thunkableWebviewerExtension.js%22%20type=%22text/javascript%22%3E%3C/script%3E--%3E%0A%20%20%20%20%3Cscript%3E%0A%20%20%20%20var%20ThunkableWebviewerExtension%20=%20(function%20()%20%7B%0A%20%20%20%20%20%20const%20postMessageToWebview%20=%20(message)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20if%20(window.ReactNativeWebView)%20%7B%0A%20%20%20%20%20%20%20%20%20%20window.ReactNativeWebView.postMessage(message);%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20window.parent.postMessage(message,%20'*');%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D;%0A%20%20%20%20%0A%20%20%20%20%20%20const%20getReceiveMessageCallback%20=%20(fxn,%20hasReturnValue)%20=%3E%20(event)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20if%20(typeof%20fxn%20===%20'function')%20%7B%0A%20%20%20%20%20%20%20%20%20%20if%20(event.data)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20dataObject;%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20dataObject%20=%20JSON.parse(event.data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20message%20is%20not%20valid%20json%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(dataObject%20&&%20dataObject.type%20===%20'ThunkablePostMessage'%20&&%20hasReturnValue)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20fxn(dataObject.message,%20(returnValue)%20=%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20returnMessageObject%20=%20%7B%20type:%20'ThunkablePostMessageReturnValue',%20uuid:%20dataObject.uuid,%20returnValue%20%7D;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20postMessageToWebview(JSON.stringify(returnMessageObject));%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(!hasReturnValue%20&&%20(!dataObject%20%7C%7C%20dataObject.type%20!==%20'ThunkablePostMessage'))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20fxn(event.data);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D;%0A%20%20%20%20%0A%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20postMessage:%20postMessageToWebview,%0A%20%20%20%20%20%20%20%20receiveMessage:%20function(fxn)%20%7B%0A%20%20%20%20%20%20%20%20%20%20const%20callbackFunction%20=%20getReceiveMessageCallback(fxn,%20false);%0A%20%20%20%20%20%20%20%20%20%20document.addEventListener('message',%20callbackFunction,%20false);%0A%20%20%20%20%20%20%20%20%20%20window.addEventListener('message',%20callbackFunction,%20false);%0A%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20receiveMessageWithReturnValue:%20function(fxn)%20%7B%0A%20%20%20%20%20%20%20%20%20%20const%20callbackFunction%20=%20getReceiveMessageCallback(fxn,%20true);%0A%20%20%20%20%20%20%20%20%20%20document.addEventListener('message',%20callbackFunction,%20false);%0A%20%20%20%20%20%20%20%20%20%20window.addEventListener('message',%20callbackFunction,%20false);%0A%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%7D;%0A%20%20%20%20%7D)();%0A%20%20%20%20%3C/script%3E%0A%3C/head%3E%0A%0A%3Cbody%3E%0A%20%20%20%20%3Cinput%20type=%22file%22%20name=%22inputfile%22%20id=%22inputfile%22%3E%0A%20%20%20%20%3Cbr%3E%0A%0A%20%20%20%20%3Cpre%20id=%22output%22%3E%3C/pre%3E%0A%20%20%20%20%0A%20%20%20%20%3Cscript%20type=%22text/javascript%22%3E%0A%20%20%20%20%20%20%20%20document.getElementById('inputfile')%0A%20%20%20%20%20%20%20%20%20%20%20%20.addEventListener('change',%20function()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20fr=new%20FileReader();%0A%20%20%20%20%20%20%20%20%20%20%20%20fr.onload=function()%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//document.getElementById('output').textContent=fr.result;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20msg%20=%20fr.result;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ThunkableWebviewerExtension.postMessage(msg);%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20fr.readAsText(this.files%5B0%5D);%0A%20%20%20%20%20%20%20%20%7D)%0A%20%20%20%20%3C/script%3E%0A%3C/body%3E%0A%3C/html%3E%0A
But I could be wrong -- I'm not very experienced with javascript

Image link from JSON and apply it to HTML

I have created a weather app where I collect the data from an API and receive it as JSON file and it is working well, I just have one issue where I want to get the icon from the link in JSON and apply it to my HTML so I can see it myself.
Very basic HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>weather api</title>
</head>
<body>
<div id="data-result"></div>
<div id="data-result-temp"></div>
<img id="data-result-icon" src="" alt=""> // I changed this a lot but did not really work.
</body>
<script src="app.js"></script>
</html>
and my JS code here
var url = "https://api.weatherapi.com/v1/current.json?key=1a4795e3c8a64d0ba4b92322202711&q=Istanbul";
const city = document.querySelector("#data-result");
const temp = document.querySelector("#data-result-temp");
const icon = document.querySelector("#data-result-icon");
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = function(data, status) {
const response = JSON.parse(xhr.response);
console.log(response);
if (xhr.status === 200) {
city.innerHTML = response.location.name;
temp.innerHTML = response.current.temp_c;
icon.innerHTML = response.current.condition.icon; // dont really know how to update
} else {
/** .. **/
}
}
xhr.onerror = function(err) {
console.log(`Network Error`, err);
};
xhr.send();
thanks!
Change the innerHTML attribute in the icon element into src attribute. Then you can display the icon. Check the below example
var url = "https://api.weatherapi.com/v1/current.json?key=1a4795e3c8a64d0ba4b92322202711&q=Istanbul";
const city = document.querySelector("#data-result");
const temp = document.querySelector("#data-result-temp");
const icon = document.querySelector("#data-result-icon");
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = function(data, status) {
const response = JSON.parse(xhr.response);
console.log(response);
if (xhr.status === 200) {
city.innerHTML = response.location.name;
temp.innerHTML = response.current.temp_c;
icon.src = "https:"+response.current.condition.icon;
} else {
/** .. **/
}
}
xhr.onerror = function(err) {
console.log(`Network Error`, err);
};
xhr.send();
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>weather api</title>
</head>
<body>
<div id="data-result"></div>
<div id="data-result-temp"></div>
<img id="data-result-icon" src="" alt="">
</body>
</html>
I think what you're looking for is:
icon.src = response.current.condition.icon;
So you're updating the src of the img rather than innerHTML.
Your current code will just return this:
<img id="data-result-icon" src="" alt="">//cdn.weatherapi.com/weather/64x64/day/113.png</img>

Trying to run a console log on php file storing json but callback error and 404 (not found)

Working with trying to learn json and ajax and how they interoperate with html and javascript
I have a php with json data inside
I am trying to get the json data formatted into the html page but I keep getting error that "callback is not a function"
I am running the php and html files on my MAMP server to simulate a api feed
I will share my html and js files
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="style.css" rel="stylesheet" type="text/css">
<script src="run2.js"></script>
<title>Ajax Demo</title>
</head>
<body>
<h1 class="title">Todays Weather Forecast</h1>
<p class="sub">Click the button the check the local weather.</p>
<button class="demo-centered" type="button" onclick="loadPhp()">Check Weather</button><br><br>
<p id="demo"></p>
</body>
</html>
var loadPhp = function(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'json';
xhr.onload = function () {
var status = xhr.status;
if (status == 200) {
callback(null, xhr.response);
} else {
callback(status);
}
};
xhr.send();
};
loadPhp('demo.php', function (err, data) {
if (err != null) {
alert('Something went wrong: ' + err);
} else {
for (var i = 0; i < data.length; i++) {
for (x in data[i]) {
console.log(data[i][x]);
}
}
}
});
PHP just in case
{"coord":{"lon":-116.8,"lat":33.03},"weather":[{"id":802,"main":"Clouds","description":"scattered clouds","icon":"03d"}],"base":"stations","main":{"temp":293.73,"feels_like":289.89,"temp_min":289.26,"temp_max":295.93,"pressure":1016,"humidity":52},"visibility":16093,"wind":{"speed":5.7,"deg":260},"clouds":{"all":40},"dt":1589408840,"sys":{"type":1,"id":5686,"country":"US","sunrise":1589374130,"sunset":1589423903},"timezone":-25200,"id":5391832,"name":"San Diego County","cod":200}
You have to create a javascript function called callback to do what the you want the callback to do.

HTML file as the response to a POST request?

I have seen questions and answers regarding this issue. For example How to return a HTML file as the response to a POST request? but am having problems implementing the solutions. Here is a sample of some php code in a directory called websiteIssue that does not work, and I am not sure why.
index.php
<?php
if(isset($_POST['page']))
{
$page = $_POST['page'];
}
else
{
$page = "";
}
include 'case.php';
?>
case.php
<?php
$testLog = 'testLog.txt';
$fileHandle = fopen('testLog.txt', 'a');
fwrite($fileHandle, '$page = '.$page."\n";
switch($page)
{
case "screen2":
include 'screen2.php';
fwrite($fileHandle, 'including screen2.php'."\n");
break;
default:
include 'screen1.php';
fwrite($fileHandle, 'including screen1.php'."\n");
break;
}
fclose($fileHandle);
?>
screen1.php
<!DOCTYPE html>
<html lang="en">
<head>
<title>screen1.php</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
<button type="button" onClick=dataSubmit({page:"screen2"})> Screen 1 => Screen2</button>
<script>
function dataSubmit(data)
{
var xmlRequest = new XMLHttpRequest();
var formData= new FormData();
for(name in data)
{
formData.append(name, data[name]);
}
xmlRequest.open('POST', 'http://localhost/websiteIssue/');
xmlRequest.send(formData);
}
</script>
</body>
</html>
screen2.php
<!DOCTYPE html>
<html lang="en">
<head>
<title>screen2.php</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
<button type="button" onClick=dataSubmit({page:"screen1"})> Screen 2 => Screen1</button>
<script>
function dataSubmit(data)
{
var xmlRequest = new XMLHttpRequest();
var formData= new FormData();
for(name in data)
{
formData.append(name, data[name]);
}
xmlRequest.open('POST', 'http://localhost/websiteIssue/');
xmlRequest.send(formData);
}
</script>
</body>
</html>
On initial load it works as I expected, the html in screen1.php is shown in the browser, but when the button on the page is pressed the html remains the same, rather than changing to that in screen2.php
The output to testText.log is something like:
$page =
including screen1.php
$page = screen2
including screen2.php
As is might be obvious, I am a newbie to this, and hopefully there is some basic thing I have not done. The browser I am running it on is Firefox. Any help would be much appreciated.
Small note:I retyped the code by hand for this post, and have not run it (the machine running the webserver is not connected to the internet), hopefully there are no syntax errors, but I may have made a typo somewhere.
By including the php file you are responding to the javascript, but you arent actually using that response for anything. If redirecting to that page is what you want, you need to use location.assign on the response. To do that:
function dataSubmit(data)
{
var xmlRequest = new XMLHttpRequest();
var formData= new FormData();
// Redirects user to response when received.
xmlRequest.onreadystatechange=function{
if (xmlRequest.readyState == 4 && xmlRequest.status == 200) {
location.assign(xmlRequest.responseText);
}
};
for(name in data)
{
formData.append(name, data[name]);
}
xmlRequest.open('POST', 'http://localhost/websiteIssue/');
xmlRequest.send(formData);
}
Based on the answer given by Felipe Souza I made the following modifications to allow the page to be dynamically modified rather than being a redirect. Thought I would share as it is another solution which some might be interested in.
index.php
<?php
if(isset($_POST['page']))
{
$page = $_POST['page'];
include 'case.php';
}
else
{
include 'base.php';
}
?>
case.php
<?php
switch($page)
{
case "screen2":
include('screen2.php');
break;
case "screen1":
include('screen1.php');
break;
default:
include('screen1.php');
break;
}
?>
base.php
<!DOCTYPE html>
<html lang="en">
<head>
<title>base.php</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
<div id="container" style="width:100%; height:100%">
<?php
if(!isset($_POST['page']))
{
$page = "";
include 'case.php';
}
?>
</div>
<script>
function dataSubmit(data)
{
var xmlRequest = new XMLHttpRequest();
var formData = new FormData();
xmlRequest.onreadystatechange=function()
{
if(xmlRequest.readyState==4 && xmlRequest.status==200)
{
document.getElementById("container").innerHTML = xmlRequest.responseText;
}
}
for(name in data)
{
formData.append(name, data[name]);
console.log(name + ":" + data[name]);
}
xmlRequest.open('POST', 'http://localhost/websiteIssue/');
xmlRequest.send(formData);
}
</script>
</body>
</html>
screen1.php
<button type"button" onClick=dataSubmit({page:"screen2"})> Screen 1 => Screen 2</button>
screen2.php
<button type"button" onClick=dataSubmit({page:"screen1"})>Screen 2 => Screen 1</button>
There seem some potential advantages in that the amount of data sent for the new screens is smaller, and (not sure if it is useful) the structure of the website is more disguised. Anyway, it is based on the answer given by Felipe Souza and supplements it (shows a dynamic approach rather than a changing pages one). Just thought I would mention it, if that was what some were looking for.

Categories