Javascript XMLHTTPRequest Not Posting XML File - javascript

I have a content generator which contians textboxes, textareas and file input controls. All controls are in HTML. Once the save button is clicked I create my XML Document with the text entered into the HTML controls. Finally, I would like the user to be prompted to download the XML File. I am hoping I can do this using a POST method with a XMLHTTPRequest in Javascript. Once the XML Document is sent with the XMLHTTPRequest here is what happens,
Chrome: HTTP Status Code: 304
IE10: Nothing happens
Again, I would like the browser to prompt the user to download the XML File. Here is my code.
function generateBaseNodes() {
var xmlString = '<?xml version="1.0"?>' +
'<sites>' +
'<site>' +
'<textareas>' +
'</textareas>' +
'<textboxes>' +
'</textboxes>' +
'<images>' +
'</images>' +
'</site>' +
'</sites>';
if (window.DOMParser) {
parser = new DOMParser();
xmlDocument = parser.parseFromString(xmlString, "text/xml");
}
else // Internet Explorer
{
xmlDocument = new ActiveXObject("Microsoft.XMLDOM");
xmlDocument.async = false;
xmlDocument.loadXML(xmlString);
}
return xmlDocument;
}
function saveXmlFile(xmlDocument) {
if (window.XMLHttpRequest) { // IE7+, Chrome. Firefox, Opera. Safari
xmlhttp = new XMLHttpRequest();
}
else { // IE5 & IE6
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open('POST', 'http://localhost:57326/ContentGenerator.html', true);
xmlhttp.setRequestHeader('Content-type','text/xml');
xmlhttp.send(xmlDocument);
}
$('document').ready(function () {
$('#templateTab a').click(function (e) {
e.preventDefault()
$(this).tab('show')
})
//Create TextArea XML elements and add them
$('#btnSave').click(function () {
var x;
var xmlDocument = generateBaseNodes();
$('.content').each(function () { // Textarea
if ($(this).attr('id') != undefined) {
if ($(this).is('textarea')) {
// create article node with control id.
articleNode = xmlDocument.createElement($(this).attr('id'));
// append node to xmldocument
x = xmlDocument.getElementsByTagName('textareas')[0];
x.appendChild(articleNode);
// append text
articleNode.appendChild(xmlDocument.createTextNode($(this).text()));
}
if ($(this).is('input[type=text]')) { // Textbox
textNode = xmlDocument.createElement($(this).attr('id'));
x = xmlDocument.getElementsByTagName('textboxes')[0];
x.appendChild(textNode);
textNode.appendChild(xmlDocument.createTextNode($(this).text()));
}
} else { // Show error if a control does not have an ID assigned to it.
alert('The' + $(this).prop('type') + 'has an undefined ID.');
}
});
$('.imageContent').each(function () {
if ($('.imageContent input[type=file]')) { // Image url
// Validate file is an image
switch ($(this).val().substring($(this).val().lastIndexOf('.') + 1).toLowerCase()) {
case 'gif': case 'jpg': case 'png':
imageNode = xmlDocument.createElement($(this).attr('id'));
x = xmlDocument.getElementsByTagName('images')[0];
x.appendChild(imageNode);
imageNode.appendChild(xmlDocument.createTextNode($(this).val()));
break;
default:
$(this).val('');
// error message here
alert("not an image");
break;
}
}
});
saveXmlFile(xmlDocument);
});
});
I SUPPOSE I SHOULD POST MY XML OUTPUT
<sites>
<site>
<textareas>
<article1>sfdsfd</article1>
<article2>dsfsdf</article2>
</textareas>
<textboxes>
<title>dsfdsf</title>
<contentHeader>sdfsdf</contentHeader>
<linkContent>sdf</linkContent>
<link>sdfsd</link>
<relatedContent>sdfsdf</relatedContent>
<contentLink>dsf</contentLink>
<relatedArticle>sdfa</relatedArticle>
<articleLink>sfdf</articleLink>
</textboxes>
<images>
<imageHeader>C:\Images\Header.png</imageHeader>
<articleImage>C:\Images\Main.png</articleImage>
<articleImage2>C:\Images\Deals.png</articleImage2>
</images>
</site>
</sites>

Is there any way to make the browser prompt to download the XML File?
Yep. Convert your data to Blob, then generate a URL from it, which you can then use in an <a>, give that <a> a download attribute and the browser now knows it's to be saved not opened, then finally simulate a click on it. For example;
function txtToBlob(txt) {
return new Blob([txt], {type: 'plain/text'});
}
function genDownloadLink(blob, filename) {
var a = document.createElement('a');
a.setAttribute('href', URL.createObjectURL(blob));
a.setAttribute('download', filename || '');
a.appendChild(document.createTextNode(filename || 'Download'));
return a;
}
function downloadIt(a) {
return a.dispatchEvent(new Event('click'));
}
// and use it
var myText = 'foobar',
myFileName = 'yay.txt';
downloadIt(
genDownloadLink(
txtToBlob(myText),
myFileName
)
);

Try using Filesaver.js to get the user to download a file in memory.
Look also into Data URI's like this:
text file

Related

Why doesn't this chrome extension work?

I want to collect the url (var name is 'url') of a webpage into a variable in a chrome extension, together with several user inputs in text inputs, and to send it to a remote php script for processing into an sql database. I am using AJAX to make the connection to the remote server. The popup.html contains a simple form for UI, and the popup.js collects the variables and makes the AJAX connection. If I use url = document.location.href I get the url of the popup.html, not the page url I want to process. I tried using chrome.tabs.query() to get the lastFocusedWindow url - the script is below. Nothing happens! It looks as though it should be straightforward to get lastFocusedWindow url, but it causes the script to fail. The manifest.json sets 'tabs', https://ajax.googleapis.com/, and the remote server ip (presently within the LAN) in permissions. The popup.html has UI for description, and some tags. (btw the response also doesn't work, but for the moment I don't mind!)
//declare variables to be used globally
var url;
// Get the HTTP Object
function getHTTPObject(){
if (window.ActiveXObject) return new ActiveXObject("Microsoft.XMLHTTP");
else if (window.XMLHttpRequest) return new XMLHttpRequest();
else {
alert("Your browser does not support AJAX.");
return null;
}
// Change the value of the outputText field THIS PART IS NOT WORKING YET
function setOutput(){
if(httpObject.readyState == 4){
//document.getElementById('outputText').value = httpObject.responseText;
"Bookmark added to db" = httpObject.responseText; // does this work?
}
}
//put URL tab function here
chrome.tabs.query(
{"active": true, "lastFocusedWindow": true},
function (tabs)
{
var url = tabs[0].url; //may need to put 'var' in front of 'url'
}
);
// Implement business logic
function doWork(){
httpObject = getHTTPObject();
if (httpObject != null) {
//get url? THIS IS OUTSTANDING - url defined from chrome.tabs.query?
description = document.getElementById('description').value;
tag1 = document.getElementById('tag1').value;
tag2 = document.getElementById('tag2').value;
tag3 = document.getElementById('tag3').value;
tag4 = document.getElementById('tag4').value;
httpObject.open("GET", "http://192.168.1.90/working/ajax.php?url="+url+"&description="+description+"&tag1="+tag1+"&tag2="+tag2+"&tag3="+tag3+"&tag4="+tag4, true);
httpObject.send(null);
httpObject.onreadystatechange = setOutput(); //THIS PART IS NOT WORKING
finalString = httpObject.responseText; //NOT WORKING
return finalString; //not working
} //close if
} //close doWork function
var httpObject = null;
var url = null;
var description = null;
var tag1 = null;
var tag2 = null;
var tag3 = null;
var tag4 = null;
// listens for button click on popup.html
document.addEventListener('DOMContentLoaded', function () {
document.querySelector('button').addEventListener('click', doWork);
});
Having no responses I first used a bookmarklet instead. The bookmarklet passes the url and title to a php script, which enters them into a db before redirecting the user back to the page they were on.
javascript:(function(){location.href='http://[ipaddress]/bookmarklet.php?url='+encodeURIComponent(location.href)+'&description='+encodeURIComponent(document.title)})()
Then I found this code which works a treat.
var urlOutput = document.getElementById('bookmarkUrl');
var titleOutput = document.getElementById('bookmarkTitle');
if(chrome) {
chrome.tabs.query(
{active: true, currentWindow: true},
(arrayOfTabs) => { logCurrentTabData(arrayOfTabs) }
);
} else {
browser.tabs.query({active: true, currentWindow: true})
.then(logCurrentTabData)
}
const logCurrentTabData = (tabs) => {
currentTab = tabs[0];
urlOutput.value = currentTab.url;
titleOutput.value = currentTab.title;
}

Apply JS onto table, which is created after page is loaded

I have got an html page, where you can put text into a textarea, click a button and then it creates an html table.
Problem is, that i am using a JS file to make my table sortable, but this JS file is not applied to tables that are created after the page itself is created.
How can i call the JS file again after the button is clicked and the table created? Or is there any other way to apply the JS file to the new table?
My problem seems to be like this problem:
Apply jquery propieties on new element created after the page is loaded
But i can't use JQuery, is there any way without it?
Example for a created table:
<div id="artikelnr2">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="table.css">
<script src="java.js"></script>
<div class="datagrid"><table class="sortable">
<thead><tr><th>Nummer</th><th>Nummer</th><th>Bezeichnung</th><th>Bemerkungen</th></tr></thead>
<tbody>
<tr><td>897-251</td><td>00.702.07803.7</td><td>5G2</td><td>-</td></tr><tr><td>897-1051</td><td>00.702.0306.7</td><td>5G1</td><td>-</td></tr><tr><td>897-1651</td><td>00.702.0307.3</td><td>5G1U</td><td>-</td></tr><tr><td>897-341</td><td>00.702.0323.9</td><td>5G2.5</td><td>-</td></tr>
</tbody>
</table></div>
</div>
I am using sorttable.js from this page:
http://www.kryogenix.org/code/browser/sorttable/
JavaScript which is called after button is clicked (pastes the content of another page into an exisiting div container):
function getOutput(url) {
var file = selectedValue()+".csv";
var value = document.getElementById("artikelnr").value;
<!---Leerzeichen entfernen-->
value = myTrim(value);
var url = url || "verarbeitung.php?eingabe="+value+"&eingabe2="+file ;
getRequest(
url, // URL for the PHP file
drawOutput, // handle successful request
drawError // handle error
);
return false;
}
// handles drawing an error message
function drawError() {
var container = document.getElementById('artikelnr2');
container.innerHTML = 'Bummer: there was an error!';
}
// handles the response, adds the html
function drawOutput(responseText) {
var container = document.getElementById('artikelnr2');
container.innerHTML = responseText;
tempResult = responseText;
}
// helper function for cross-browser request object
function getRequest(url, success, error) {
var req = false;
try{
// most browsers
req = new XMLHttpRequest();
} catch (e){
// IE
try{
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
// try an older version
try{
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
return false;
}
}
}
if (!req) return false;
if (typeof success != 'function') success = function () {};
if (typeof error!= 'function') error = function () {};
req.onreadystatechange = function(){
if(req.readyState == 4) {
return req.status === 200 ?
success(req.responseText) : error(req.status);
}
}
req.open("GET", url, true);
req.send(null);
return req;
}
So this is a suggestion as a major part of your code is not available.
In your existing code, where you create the new table, you need to add/run the following:
sorttable.makeSortable(newTableObject);
The newTableObject reference you either can get straight from your existing code or by calling document.getElementById(idOfTheTableIJustAdded) after your added the new table to the DOM.
Src: http://www.kryogenix.org/code/browser/sorttable/
Update after question edit:
In this script function you should be able to do like this
function drawOutput(responseText) {
var container = document.getElementById('artikelnr2');
container.innerHTML = responseText;
//tempResult = responseText;
var newTableObject = container.querySelector(".sortable");
sorttable.makeSortable(newTableObject);
}

Storing variables from parsed text file using javascript

The text file contains information that I want to use with my website for logging in purposes
Text file contains the following..line by line
user:password
user2:user2password
I have tried using blob to read the text file but variables are not getting stored so I would like to know where I am going wrong or if I am even able to read the file using this method
function readFile(){
var fileName = txtName.value;
file = login.txt;
var blob = file.read();
var readText = blob.text;
var lines = data.split("\n && : " );
//Adding the file content to the label placed
lblFileContent.setText(readText);
Ti.API.info(readText);
// dispose of file handle & blob.
file = null;
blob = null;
}
I've used this in the past to read a txt-file:
JavaScript (jQuery):
function readFile() {
$.post('path/to/php/read_file.php', {
dir: 'path/to/file',
file: 'file_name.txt',
},function(file_contents) {
if (file_contents != '') {
//your code here
}
});
}
PHP:
<?php
/* This script is invoked by 'index.html'.
* This script gets the content of the file that has been changed by
* the admin, and uses it to determine the path of the file
* that is currently set by the admin.
*/
$dir = $_POST["dir"];
$file = $_POST["file"];
$contents= '';
if ($dhandle = opendir("$dir")) {
while (false !== ($entry = readdir($dhandle))) {
if ($entry != "." && $entry != "..") {
if ($entry == $file) {
$entry_path = $dir.DIRECTORY_SEPARATOR.$entry;
$fhandle = fopen($entry_path, 'r');
$value = fread($fhandle, filesize($entry_path));
fclose($fhandle);
}
}
}
closedir($dhandle);
echo "$contents";
}
?>
You might want to try HTML 5 file API
1) To specify the text file add an input type file HTML tag (this will show a file selection dialog, if clicked).
<input type="file" id="myFileId">
2) Add a listener that will be executed when you choose a file, which triggers a 'change' event.
document.getElementById('myFileId').addEventListener('change', function(e) {
});
3) In the EventListener use FileReader to read your text file.
document.getElementById('myFileId').addEventListener('change', function(e) {
var file = document.getElementById('myFileId').files[0];
var reader = new FileReader();
reader.onload = function(e) {
var userPass = reader.result.split(" "); // split by space
// userPass is an array where each element has a user:pass
// do your stuff
} // onload
reader.readAsText(file);
});
You might want to check for file type/size before trying to read it.
Here is a solution you may be interested in.
Text file named login.txt containing I'm reading this file using JavaScript.
user
myuser
password
myuserpassword
My JavaScript code
var loadXMLDoc=function(){
var Credentials={};
if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else {// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==0){
var temp=xmlhttp.responseText.split('\n');
for(i=0;i<temp.length;i++){
switch(temp[i].trim()){
case "user":
case "User":
Credentials.Username=temp[i+1];
break;
case "password":
case "Password":
Credentials.Password=temp[i+1];
break;
}
}
console.log(Credentials); //Printing the object in the console.
}
}
xmlhttp.open("GET","login.txt",true);
xmlhttp.send();
}
HTML input. Please note I'm call the js function here.
<input type="button" id="load" value="Click me!" onclick="loadXMLDoc();"/>
Print the password in console with a function getPassword("myuser").
var getPassword=function(username){ // It takes one string parameter which is the username.
var password="";
if(Credentials.Username){
if(Credentials.Username.trim()==username) password=Credentials.Password;
}
return password;
};

InnerHtml problem in Internet Explorer

I am having problem with applying ajax on IE.I am applying innerHtml on select tag but it is not working my ajax code is
function AjaxF(ftype, cid) {
var httpxml;
try {
// Firefox, Opera 8.0+, Safari
httpxml = new XMLHttpRequest();
}
catch (e) {
// Internet Explorer
try {
httpxml = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
httpxml = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {
alert("Your browser does not support AJAX!");
return false;
}
}
}
function stateck() {
if (httpxml.readyState == 4) {
var myarray = httpxml.responseText;
if (ftype == 'Files') {
document.getElementById('temp_thumbnail').innerHTML = myarray;
document.getElementById('temp_mainfiles').innerHTML = myarray;
document.getElementById('temp_preview').innerHTML = myarray;
document.getElementById('temp_image').innerHTML = myarray;
}
else {
document.getElementById('temp_thumbnail').innerHTML = myarray;
document.getElementById('temp_main').innerHTML = myarray;
document.getElementById('temp_image').innerHTML = myarray;
}
}
}
var url = "ajax/files_ajax.php";
url = url + "?filetype=" + ftype + "&customerid=" + cid;
url = url + "&sid=" + Math.random();
httpxml.onreadystatechange = stateck;
httpxml.open("GET", url, true);
httpxml.send(null);
}
My php code for creating option is.I am getting the values in filetype and it is working fine on other browsers
$sql="select name ,id from temporary_upload where type ='$filetype' AND customer_id='$customer_id'";
$result=mysql_query($sql);
while($rows=mysql_fetch_array($result))
{
$s.="<option id='' name='' selected='selected' value='". $rows['name'] ."'>". $rows['name'] ."</option>";
}
echo $s;
My html for this code is
<select id="temp_thumbnail" name="temp_thumbnail" style="width:452px">
<option></option>
</select>
I have searched for this error on many forums.They all are saying that innerHtml with select has error in IE can anyone help me to resolve this issue.That I can populate my select option.
Thanks in advance
some years ago, i had a similar problem with IE6. if i remember right, i solved this by replacing the whole select-element instead of just replacing the innerHTML (the option-elements).
to do this, you'll have to change the file called via ajax to output the start- and end-tag of your select-element, too. put the select-elemet on your html-site into another element with an id (if there isn't already one you havn't posted) and replace the innerHTML of that outer element.
EDIT: the link gnur posted describes exactly this workaround, so it seems like i remember right ;)
Not a fan of the solutions where they want you to remove the select and than add it back. Kills all the event handlers. Wrote a little function that tries to set the innerHTML. If setting the innerHTML results in no options being added, it rewrites the function so it will create an element and clone its options.
function addOptionsToSelect( selectId, optStr){
var sel = document.getElementById(selectId)
sel.options.length = 0;
sel.innerHTML = optStr;
if(sel.options.length===0){
(addOptionsToSelect = function( selectId, optStr){
var div = document.createElement("div");
div.innerHTML = "<select>" + optStr + "</select>";
var newSelect = div.getElementsByTagName("select")[0];
var sel = document.getElementById(selectId);
sel.options.length = 0;
for(var i=0;i<newSelect.options.length;i++){
var cpy = newSelect.options[i].cloneNode(true);
sel.appendChild(cpy);
}
div = newSelect = sel = null;
})
( selectId, optStr);
}
}
Running Example
This may work for you in IE and FF, of course a bit of modification depending on how and where you want to place the new options in the select ...
function addmore(){
var select=document.getElementById('myselect');
var theindex=select.options[select.selectedIndex];
var option=document.createElement('option');
option.text='text_4';
option.value='value_4';
try{
select.add(option,theindex);
}
catch(e){
//and for ie
select.add(option,select.selectedIndex);
}
}
This page has an excellent work around:

How to download multiple files in one shot in IE

I want to download multiple files on click of a button in jsp.
I am using the following code in the js to call one servlet twice.
var iframe = document.createElement("iframe");
iframe.width = iframe.height = iframe.frameBorder = 0;
iframe.scrolling = "no";
iframe.src = "/xyz.jsp?prodId=p10245";
document.getElementById("iframe_holder").appendChild(iframe);
var iframe2 = document.createElement("iframe");
iframe2.width = iframe2.height = iframe2.frameBorder = 0;
iframe2.scrolling = "no";
iframe2.src = "/xyz.jsp?prodId=p10243";
document.getElementById("iframe_holder").appendChild(iframe2);
In xyz.jsp i am calling the servlet which downloads the file from a path and send it on the browser.
Issue is that it is working safari,firefox but not in IE.
We cannot download multiple files with IE?
By design, non-user-initiated file downloads are blocked in IE. That inherently means that it should not be possible to download more than one file as the result of a single user-click.
I've used the following code to download multiple files in IE and Chrome
function downloadFile(url)
{
var iframe = document.createElement("iframe");
iframe.src = url;
iframe.style.display = "none";
document.body.appendChild(iframe);
}
function downloadFiles(urls)
{
downloadFile(urls[0]);
if (urls.length > 1)
window.setTimeout(function () { downloadFiles(urls.slice(1)) }, 1000);
}
You pass an array of URLs to the downloadFiles() function, which will call downloadFile() for each with a short delay between. The delay seems to be the key to getting it to work!
I had a similar need but also wanted the downloads to occur in a new window.
I created a js to download a list of files, and a php to do the actual file saving. I used the above as a starting point, and the PHP start from (okay, can't find the original source). I encode the passed URI so spaces in the file names don't cause troubles.
(function () {
"use strict";
var files = [], // Array of filename strings to download
newWindow, // New window to handle the download request
secondsBetweenDownloads; // Wait time beteen downloads in seconds
//
// Download a file using a new window given a URI
//
function downloadFile(uri) {
if (!newWindow) {
newWindow = window.open('',
'',
'width=1500 height=100');
}
if (newWindow) {
newWindow.location =
'saveAs.php?' +
'file_source=' + encodeURI(uri);
newWindow.document.title = "Download File: " + uri;
} else {
console.log("Unable to open new window. Popups blocked?");
}
}
//
// Download all files specified in the files[] array from siteName.
// Download the file at array position zero, then set a timeout for
// secondsBetweenDownloads seconds
//
function downloadFiles(siteName) {
var showTime = new Date();
console.log(
showTime.toTimeString().substring(0,8) +
" Starting download for: " + files[0]
);
// Skip any empty entries, download this file
if (files[0].length > 0) downloadFile(siteName + files.splice(0, 1));
if (files.length > 0) { // If more files in array
window.setTimeout(function () { // Then setup for another iteration
downloadFiles(siteName );
}, secondsBetweenDownloads * 1000); // Delay for n seconds between requests
} else {
newWindow.close(); // Finished, close the download window
}
}
//
// Set the web site name and fill the files[] array with the files to download
// then kick off the download of the files.
//
$(document).ready(function () {
var
siteName** = "http://www.mysteryshows.com/thank-you/";
secondsBetweenDownloads** = 35; // N seconds delay between requests
files = [
"show1.mp3",
"show2.mp3"
];
downloadFiles(siteName, files);
});
}());
The HTML for the page is simple. Basically any syntax-compliant page will do.
The saveAs.php page which the js file uses in the newWindow.location line is php only.
<?php
if (isset($_GET['file_source'])) {
$fullPath = $_GET['file_source'];
if($fullPath) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
case "pdf":
header("Content-Disposition: attachment;
filename=\"".$path_parts["basename"]."\""); // use 'attachment' to
// force a download
header("Content-type: application/pdf"); // add here more headers for
// diff. extensions
break;
default;
header("Content-type: **application/octet-stream**");
header("Content-Disposition:
filename=\"".$path_parts["basename"]."\"");
}
if($fsize) {//checking if file size exist
header("Content-length: $fsize");
}
$request = $path_parts["dirname"] . '/' .
rawurlencode($path_parts["basename"]);
readfile($request);
exit;
}
}
?>
I used rawurlencode on just the 'basename' portion of the URI to ensure it was a valid, encoded request.
It can be done by creating a blob using the file source URL. I have tested this with image and PDF files in IE 11.
if (navigator.msSaveBlob) {
var xhr = new XMLHttpRequest();
xhr.open('GET', file_url, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var blob = this.response;
navigator.msSaveBlob(blob, file_name);
}
}
xhr.onerror = function(e) {
alert("Error " + e.target.status + " occurred while receiving the document.");
}
xhr.send();
}
I got this idea when I came across this: Getting BLOB data from XHR request

Categories

Resources