JavaScript XMLHttpRequest return status 0 - javascript

I'm pretty new to JavaScript / TypeScript and I was writing this tiny piece of TS code to retreive the HTML from another page on my server and put it on a <div id='container'> tag.
let container = document.getElementById("container") as HTMLDivElement;
let req = new XMLHttpRequest();
function getContent(page: string): string {
let content = "";
const basePath = "content/";
const url = basePath + page;
req.open("GET", url);
req.send();
content = req.responseText;
container.innerHTML = content;
console.log(req.status);
return content;
}
getContent('home');
Now, when I open the page on the browser (I'm using GitHub Pages for hosting) all I get is a blank page and a req.status of 0 in the console.
Of course the file content/home.html exists. I tried both getContent('home') and getContent(home.html) but neither worked.
What am I doing wrong?
Thank you to all.

Related

How to write data in JSON file in the EJS template file [duplicate]

I want to Write Data to existing file using JavaScript.
I don't want to print it on console.
I want to Actually Write data to abc.txt.
I read many answered question but every where they are printing on console.
at some place they have given code but its not working.
So please can any one help me How to actually write data to File.
I referred the code but its not working:
its giving error:
Uncaught TypeError: Illegal constructor
on chrome and
SecurityError: The operation is insecure.
on Mozilla
var f = "sometextfile.txt";
writeTextFile(f, "Spoon")
writeTextFile(f, "Cheese monkey")
writeTextFile(f, "Onion")
function writeTextFile(afilename, output)
{
var txtFile =new File(afilename);
txtFile.writeln(output);
txtFile.close();
}
So can we actually write data to file using only Javascript or NOT?
You can create files in browser using Blob and URL.createObjectURL. All recent browsers support this.
You can not directly save the file you create, since that would cause massive security problems, but you can provide it as a download link for the user. You can suggest a file name via the download attribute of the link, in browsers that support the download attribute. As with any other download, the user downloading the file will have the final say on the file name though.
var textFile = null,
makeTextFile = function (text) {
var data = new Blob([text], {type: 'text/plain'});
// If we are replacing a previously generated file we need to
// manually revoke the object URL to avoid memory leaks.
if (textFile !== null) {
window.URL.revokeObjectURL(textFile);
}
textFile = window.URL.createObjectURL(data);
// returns a URL you can use as a href
return textFile;
};
Here's an example that uses this technique to save arbitrary text from a textarea.
If you want to immediately initiate the download instead of requiring the user to click on a link, you can use mouse events to simulate a mouse click on the link as Lifecube's answer did. I've created an updated example that uses this technique.
var create = document.getElementById('create'),
textbox = document.getElementById('textbox');
create.addEventListener('click', function () {
var link = document.createElement('a');
link.setAttribute('download', 'info.txt');
link.href = makeTextFile(textbox.value);
document.body.appendChild(link);
// wait for the link to be added to the document
window.requestAnimationFrame(function () {
var event = new MouseEvent('click');
link.dispatchEvent(event);
document.body.removeChild(link);
});
}, false);
Some suggestions for this -
If you are trying to write a file on client machine, You can't do this in any cross-browser way. IE does have methods to enable "trusted" applications to use ActiveX objects to read/write file.
If you are trying to save it on your server then simply pass on the text data to your server and execute the file writing code using some server side language.
To store some information on the client side that is considerably small, you can go for cookies.
Using the HTML5 API for Local Storage.
If you are talking about browser javascript, you can not write data directly to local file for security reason. HTML 5 new API can only allow you to read files.
But if you want to write data, and enable user to download as a file to local. the following code works:
function download(strData, strFileName, strMimeType) {
var D = document,
A = arguments,
a = D.createElement("a"),
d = A[0],
n = A[1],
t = A[2] || "text/plain";
//build download link:
a.href = "data:" + strMimeType + "charset=utf-8," + escape(strData);
if (window.MSBlobBuilder) { // IE10
var bb = new MSBlobBuilder();
bb.append(strData);
return navigator.msSaveBlob(bb, strFileName);
} /* end if(window.MSBlobBuilder) */
if ('download' in a) { //FF20, CH19
a.setAttribute("download", n);
a.innerHTML = "downloading...";
D.body.appendChild(a);
setTimeout(function() {
var e = D.createEvent("MouseEvents");
e.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
a.dispatchEvent(e);
D.body.removeChild(a);
}, 66);
return true;
}; /* end if('download' in a) */
//do iframe dataURL download: (older W3)
var f = D.createElement("iframe");
D.body.appendChild(f);
f.src = "data:" + (A[2] ? A[2] : "application/octet-stream") + (window.btoa ? ";base64" : "") + "," + (window.btoa ? window.btoa : escape)(strData);
setTimeout(function() {
D.body.removeChild(f);
}, 333);
return true;
}
to use it:
download('the content of the file', 'filename.txt', 'text/plain');
Try
let a = document.createElement('a');
a.href = "data:application/octet-stream,"+encodeURIComponent("My DATA");
a.download = 'abc.txt';
a.click();
If you want to download binary data look here
Update
2020.06.14 I upgrade Chrome to 83.0 and above SO snippet stop works (reason: sandbox security restrictions) - but JSFiddle version works - here
Above answer is useful but, I found code which helps you to download text file directly on button click.
In this code you can also change filename as you wish. It's pure javascript function with HTML5.
Works for me!
function saveTextAsFile()
{
var textToWrite = document.getElementById("inputTextToSave").value;
var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'});
var fileNameToSaveAs = document.getElementById("inputFileNameToSaveAs").value;
var downloadLink = document.createElement("a");
downloadLink.download = fileNameToSaveAs;
downloadLink.innerHTML = "Download File";
if (window.webkitURL != null)
{
// Chrome allows the link to be clicked
// without actually adding it to the DOM.
downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
}
else
{
// Firefox requires the link to be added to the DOM
// before it can be clicked.
downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
downloadLink.onclick = destroyClickedElement;
downloadLink.style.display = "none";
document.body.appendChild(downloadLink);
}
downloadLink.click();
}
const data = {name: 'Ronn', age: 27}; //sample json
const a = document.createElement('a');
const blob = new Blob([JSON.stringify(data)]);
a.href = URL.createObjectURL(blob);
a.download = 'sample-profile'; //filename to download
a.click();
Check Blob documentation here - Blob MDN to provide extra parameters for file type. By default it will make .txt file
In the case it is not possibile to use the new Blob solution, that is for sure the best solution in modern browser, it is still possible to use this simpler approach, that has a limit in the file size by the way:
function download() {
var fileContents=JSON.stringify(jsonObject, null, 2);
var fileName= "data.json";
var pp = document.createElement('a');
pp.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(fileContents));
pp.setAttribute('download', fileName);
pp.click();
}
setTimeout(function() {download()}, 500);
$('#download').on("click", function() {
function download() {
var jsonObject = {
"name": "John",
"age": 31,
"city": "New York"
};
var fileContents = JSON.stringify(jsonObject, null, 2);
var fileName = "data.json";
var pp = document.createElement('a');
pp.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(fileContents));
pp.setAttribute('download', fileName);
pp.click();
}
setTimeout(function() {
download()
}, 500);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="download">Download me</button>
Use the code by the user #useless-code above (https://stackoverflow.com/a/21016088/327386) to generate the file.
If you want to download the file automatically, pass the textFile that was just generated to this function:
var downloadFile = function downloadURL(url) {
var hiddenIFrameID = 'hiddenDownloader',
iframe = document.getElementById(hiddenIFrameID);
if (iframe === null) {
iframe = document.createElement('iframe');
iframe.id = hiddenIFrameID;
iframe.style.display = 'none';
document.body.appendChild(iframe);
}
iframe.src = url;
}
I found good answers here, but also found a simpler way.
The button to create the blob and the download link can be combined in one link, as the link element can have an onclick attribute. (The reverse seems not possible, adding a href to a button does not work.)
You can style the link as a button using bootstrap, which is still pure javascript, except for styling.
Combining the button and the download link also reduces code, as fewer of those ugly getElementById calls are needed.
This example needs only one button click to create the text-blob and download it:
<a id="a_btn_writetofile" download="info.txt" href="#" class="btn btn-primary"
onclick="exportFile('This is some dummy data.\nAnd some more dummy data.\n', 'a_btn_writetofile')"
>
Write To File
</a>
<script>
// URL pointing to the Blob with the file contents
var objUrl = null;
// create the blob with file content, and attach the URL to the downloadlink;
// NB: link must have the download attribute
// this method can go to your library
function exportFile(fileContent, downloadLinkId) {
// revoke the old object URL to avoid memory leaks.
if (objUrl !== null) {
window.URL.revokeObjectURL(objUrl);
}
// create the object that contains the file data and that can be referred to with a URL
var data = new Blob([fileContent], { type: 'text/plain' });
objUrl = window.URL.createObjectURL(data);
// attach the object to the download link (styled as button)
var downloadLinkButton = document.getElementById(downloadLinkId);
downloadLinkButton.href = objUrl;
};
</script>
Here is a single-page local-file version for use when you need the extra processing functionality of a scripting language.
Save the code below to a text file
Change the file extension from '.txt' to '.html'
Right-click > Open With... > notepad
Program word processing as needed, then save
Double-click html file to open in default browser
Result will be previewed in the black box, click download to get the resulting text file
Code:
<!DOCTYPE HTML>
<HTML>
<HEAD>
</HEAD>
<BODY>
<SCRIPT>
// do text manipulation here
let string1 = 'test\r\n';
let string2 = 'export.';
// assemble final string
const finalText = string1 + string2;
// convert to blob
const data = new Blob([finalText], {type: 'text/plain'});
// create file link
const link = document.createElement('a');
link.innerHTML = 'download';
link.setAttribute('download', 'data.txt');
link.href = window.URL.createObjectURL(data);
document.body.appendChild(link);
// preview the output in a paragraph
const htmlBreak = string => {
return string.replace(/(?:\r\n|\r|\n)/g, '<br>');
}
const preview = document.createElement('p');
preview.innerHTML = htmlBreak(finalText);
preview.style.border = "1px solid black";
document.body.appendChild(preview);
</SCRIPT>
</BODY>
</HTML>

Unable to check for if a file exists and perform statement

I am very new to javascripting and html.
I have built a web page that is mostly used to load either txt or other html pages using tag.
But I am trying to create a validation statement to check if the source file exists and load the iframe or if it doesn't to display a message.
I have tried the below code, but it just doesn't work.
Can anyone please help me?
<script>
var url = checkfile('../folder/test.html');
if (url.exists()){
<iframe id = "allviewer" src = "../folder/test.html"> < /iframe>
} else {
< p > This file does not exist < /p>
}
</script>
You should already avoid adding the iframe in the script tag, if you want to check if the file exists you can use ajax but the ajax already allows you to see the content so the iframe is no longer really necessary
<script type="text/javascript">
function url_exists(url) {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest;
xhr.open("GET", url, false);
xhr.send();
if (xhr.status == 200) resolve(xhr);
else reject(xhr.status);
})
}
const file = '../folder/test.html';
url_exists(file).then(t => {
console.log(t.response); // show file content in the console
ouputNode.innerHTML = `<iframe id="allviewer" src="${file}"></iframe>`;
}).catch(e => {
// on error
});
</script>
<div id="ouputNode"></div>

pdfkit Browser - "Uncaught ReferenceError: fs is not defined" when using custom fonts

This question may be asked previously but they have no answer. I try to create a pdf file using pdfkit library with Arabic language support. So, first I downloaded a prebuilt version of pdfkit (which is assumed to work in browser) from here.
Then I wrote this code for adding an Arabic font (like in the docs)
const doc = new PDFDocument;
var text_arabic = "مرحبا مَرْحَبًا";
// Using a TrueType font (.ttf)
doc.font('./trado.ttf') // --> this line gives the error.
.text(text_arabic)
.moveDown(0.5);
The error is:
Uncaught ReferenceError: fs is not defined
at Object.fontkit.openSync (pdfkit.js:10949)
at Function.PDFFont.open (pdfkit.js:451)
at PDFDocument.font (pdfkit.js:2227)
at main.js:22
pdfkit.js from line 10949:
fontkit.openSync = function (filename, postscriptName) {
var buffer = fs.readFileSync(filename); / --> error
return fontkit.create(buffer, postscriptName);
};
So, I think 'fs' belongs to node.js part with require('fs') but anyway I don't know the solution. What is the solution then? Thanks in advance!
Here is the simple solution;
Don't forget to add pre-built pdfkit.js and blob-stream.js files
Copy below js code and include it in your html
Put your fonts to the same place with html/js (like trado.ttf)
Change the getFont(...) according to your font name
Done!
Important Notes:
If you run it without any server, chrome will give CORS policy error. (See this to disable just for try)
When you move your files to a server, or running in local server, there will be no CORS error.
Last and most importantly, give some times to xhr.onload. Because of that we create writeToPDF() function seperately for using with a button after loading.
const doc = new PDFDocument;
const stream = doc.pipe(blobStream());
var embeddedFonts = (function() {
var fontCollection = {};
function getFont(name, src) {
var xhr = new XMLHttpRequest();
xhr.open('GET', src, true);
xhr.responseType = "arraybuffer";
xhr.onload = function(evt) {
var arrayBuffer = xhr.response;
if (arrayBuffer) {
fontCollection[name] = new Uint8Array(arrayBuffer);
registerEmbeddedFonts(doc, embeddedFonts);
} else {
error = "Error downloading font resource from " + src;
}
};
xhr.send(null);
}
getFont("Trado", 'trado.ttf');
return fontCollection;
}());
function registerEmbeddedFonts(doc, fontCollection) {
doc.registerFont("Trado", fontCollection["Trado"]);
}
function writeToPDF() {
doc.fontSize(40);
doc.font('Trado').text('مَرْحَبًا');
doc.end();
stream.on('finish', function() {
// get a blob you can do whatever you like with
const blob = stream.toBlob('application/pdf');
// or get a blob URL for display in the browser
const url = stream.toBlobURL('application/pdf');
var frame = document.getElementById("pdfFrame");
frame.src = url;
});
}
<script src="https://github.com/foliojs/pdfkit/releases/download/v0.8.0/pdfkit.js"></script>
<script src="https://github.com/devongovett/blob-stream/releases/download/v0.1.3/blob-stream.js"></script>
<iframe id="pdfFrame" src="" width="300" height="300"> </iframe>
<button type="button" onclick="writeToPDF();">Write to PDF</button>
<!-- This example doesn't work because of missing trado.ttf font file.
Try to run at your PC -->

delay in dynamic loading of external Javascript(JSON) file for Phonegap

im trying to load a external js (json) file (PhoneGap app) whose structure is like
var localString ={
"tag1": "Username",
"tag2": "Password",
"submit": "Submit"
}
and using the below code to load it at runtime, the newlocale variable holds the name of the file to be loaded for eg: if locale is english-USA then var resourcePath = en-US.js. The issue is the first time i run this code i get this error "ReferenceError: localstring is not defined" , but it loads the external strings the second time i load it. In between i am calling the external file using "select" tag in html5. Can someone provide some insights on where im going wrong or any pointers to overcome this issue.
var newlocale = window.DeviceCulture.get();
local(newlocale);
function local(lang) {
try {
var resourcePath = lang + '.js';
var scriptEl = document.createElement('script');
scriptEl.type = 'text/javascript';
scriptEl.src = resourcePath;
alert(resourcePath);
document.getElementsByTagName("head")[0].appendChild(scriptEl);
//$('head').append(scriptEl);
//var localString = window.localString;
document.getElementById("07").value = localString['submit'];
} catch (e) {
errorEvent(e);
}
}
Okay I believe the root cause of your problem is that you are appending the tag for the .js file into the head after the page is already loaded. When you first load a page the script tages are downloaded and interpreted in order so b can depend on a. However, the way you are doing it is non-blocking so that the script you load is not fully loaded by the time you get to the next line in your code which tries to access "localString".
To solve this I'd restructure your code somewhat. First forget about making local files JavaScript. Just make them plain text .json files. For example:
{
"tag1": "Username",
"tag2": "Password",
"submit": "Submit"
}
Then I'd load that file using XHR instead of script tag insertion. Something like:
var newlocale = window.DeviceCulture.get();
var localString;
local(newlocale);
function local(lang) {
try {
var resourcePath = lang + '.json';
var request = new XMLHttpRequest();
request.open("GET", resourcePath, true);
request.onreadystatechange = function(){
if (request.readyState == 4) {
if (request.status == 200 || request.status == 0) {
localString = JSON.parse(request.responseText);
// at this point localString is loaded with the new language
document.getElementById("07").value = localString['submit'];
}
}
}
request.send();
} catch (e) {
errorEvent(e);
}
}
and that should take care of things.

My Firefox extension to inject CSS wont work

I am busy developing a firefox extension. I am using the Add-on Builder
What it will do:
Get an ID from a PHP page (XMLHttpRequest)
Call another function and send that ID with it
That function inserts CSS with a link tag created by javascript
My Problem:
It won't work. If I alert the currenttheme variable, nothing happens. So the XMLHttpRequest doesn't seem to work.
My code:
main.js:
var Widget = require("widget").Widget;
var tabs = require('tabs');
exports.main = function() {
var pageMod = require("page-mod");
var data = require("self").data;
scriptFiles = data.url("s.js");
pageMod.PageMod({
include: "*.facebook.com",
contentScriptWhen: 'ready',
contentScriptFile: scriptFiles
});
s.js
function addCSS(theTheme) {
var s = document.createElement('link');
s.type = 'text/css';
s.rel = 'stylesheet';
s.href = theTheme+'.css';
(document.head||document.documentElement).appendChild(s);
}
function getData() {
client = new XMLHttpRequest();
try{
client.open('GET','http://localhost:8888/istyla/login/popuplogin/myaccount.php');
} catch (e){
alert( "error while opening " + e.message );
}
client.onreadystatechange = function(){
if (client.readyState ==4){
user_data = client.responseText;
window.user_data = user_data;
var currenttheme = user_data;
window.currenttheme = currenttheme;
addCSS(currenttheme);
}
}
client.send(null);
}
getData();
P.S. The CSS file is in the data folder.
Im very new to this so not sure if I can help. Have you had a look in the error console(ctrl+shift+j) if its complaining about anything? You can console.log() and it will show in here.
Maybe use the Request lib instead of XMLHttpRequest
Here is a snippet from my code:
var Request = require("request").Request;
getUserDetails : function(userID, callback)
{
Request({
url: Proxy.remoteUrl,
content : {command:'getUser',UserID:userID},
onComplete: function(response) {callback(response.json)}
}).get();
}
Content scripts run with the privileges of the page that they are in. So if the page isn't allowed to load http://localhost/, your content script won't be able to do it either. You don't get an immediate error due to CORS but the request will fail nevertheless. What you need to do is to send a message to main.js so that it does the request (extension code is allowed to request any URI) and sends the data back to the content script.
As said, the content script has the same privileged of the web page where is attached, that is meaning you're under the Same Origin Policy.
You can solve the issue as suggested, so sent a message to the add-on code (that is not restricted by the SOP) and post the result back to the content script.
Here an example how the code could be: https://groups.google.com/d/topic/mozilla-labs-jetpack/VwkZxd_mA7c/discussion

Categories

Resources