XMLHttpRequest fails reading XML InfoPath form due to mso-application line - javascript

I'm trying to create an ASPX page on my SharePoint site to read existing InfoPath forms. Testing locally with JavaScript and XMLHttpRequest worked fine but when the page is uploaded to SharePoint something very odd happens if the XML file has a specific line of data in it. When testing with simple XML files this line causes a problem:
<?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.4"?>
When present in the XML file I'm trying to read, something odd happens. Instead of getting the contents of the file I get what appears to be an HTML page from SharePoint. The page doesn't display anything and has references to InfoPath and SharePoint libraries. I have no idea where the HTML is coming from. Removing that single line from the XML file causes everything to work as expected. Running outside of SharePoint appears to work as well. I will include a sample XML file and code I used to test.
Update : If the input file extension is TXT and not XML then the problem goes away. I assume this means that SharePoint is running code when XML files are read and injecting itself into my get request.
<?xml version="1.0" encoding="utf-8"?>
<?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.4"?>
<my:myFields xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2017-05-05T14:19:13">
<my:User_Name>Joe</my:User_Name>
<my:Email_Address>joe.smith#abc.com</my:Email_Address>
</my:myFields>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="lib/jquery/jquery-3.4.1.min.js"></script>
<title></title>
<script>
var oReq = new XMLHttpRequest();
oReq.addEventListener("progress", updateProgress);
oReq.addEventListener("error", transferFailed);
oReq.addEventListener("abort", transferCanceled);
oReq.addEventListener("loadend", transferComplete);
function Test_Req_xml() {
console.log("starting test_req_xml function");
let filename = document.getElementById('inFileName').value;
console.log("file name " + filename);
oReq.addEventListener("load", transferComplete_xml);
oReq.open("GET", filename);
oReq.responseType = "document";
oReq.send();
}
var transferComplete_xml = function (response) {
console.log({ 'transferComplete xml response:': response });
console.log({ 'oReq.responseXML': oReq.responseXML });
console.log({ 'oReq.responseType': oReq.responseType });
console.log({ 'oReq.responseURL': oReq.responseURL });
console.log({ 'oReq': oReq });
parseFile(oReq.responseXML.documentElement.outerHTML);
};
// progress on transfers from the server to the client (downloads)
function updateProgress(oEvent) {
if (oEvent.lengthComputable) {
var percentComplete = oEvent.loaded / oEvent.total * 100;
console.log("percent " + percentComplete);
} else {
// Unable to compute progress information since the total size is unknown
console.log("loaded is " + oEvent.loaded);
}
}
function transferComplete(evt) {
console.log("The transfer is complete.");
}
function transferFailed(evt) {
console.log("An error occurred while transferring the file.");
}
function transferCanceled(evt) {
console.log("The transfer has been canceled by the user.");
}
//this will parse XML file and output it to website
var parseFile = function (text) {
var xmlDoc = $.parseXML(text),
$xml = $(xmlDoc),
$email = $xml.find("Email_Address"),
$naming = $xml.find("User_Name");
console.log({ 'xmldoc ': xmlDoc });
var currentdate = new Date();
var datetime = currentdate.getDate() + "/" + (currentdate.getMonth() + 1) + "/" + currentdate.getFullYear() + " # " + currentdate.getHours() + ":" + currentdate.getMinutes() + ":" + currentdate.getSeconds();
$("#output").empty();
$("#output").append("<br/>");
$("#output").append("<span>Date: " + datetime + "</span><br/>");
$("#output").append("<span>Name: " + $naming.text() + "</span><br/>");
$("#output").append("<span>Email: " + $email.text() + "</span><br/>");
};
</script>
</head>
<body>
<div class="row m-sm">
<span>File name: </span><input id="inFileName" type="text" class="form-control" placeholder="" value="test_xml_file3.xml">
</div>
<div class="row m-sm">
<button id="btnTest3" class="btn btn-outline-secondary" type="button" onclick="Test_Req_xml()">Test xml </button>
</div>
<div class="row m-sm">
<ul id="output"></ul>
</div>
</body>
</html>

I am not entirely sure how it happens but my guess is SharePoint Online is intercepting the get request for files with the XML extension and when it finds the line below it attempts to run some code against the request. I don't see any issues when the file doesn't have an XML extension, nor do I see an issue when the line below is missing from an XML file. Now I need to find out if there is a way around this.
<?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.4"?>

Related

how to load data using a javascript

I have almost zero experience with Javascript , I need to use this Javascript in my php script .
<script>
let arr = ["alfa", "beta", "charlie"]
const updateResult = query => {
let resultList = document.querySelector(".result");
resultList.innerHTML = "";
arr.map(algo =>{
query.split(" ").map(word =>{
if(algo.toLowerCase().indexOf(word.toLowerCase()) != -1){
resultList.innerHTML += `<li class="list-group-item">${algo}</li>`;
}
})
})
}
updateResult("")
</script>
This script load the data using
let arr =
However suppose I have all the data specified there in a file in this format
c:/data/mydata.txt
and the data.txt contains data in this form (one data per row)
alfa
bravo
charlie
Now how should I change the javascript above to load the data from c:/data/mydata.txt and not using
let arr = ["alfa", "beta", "charlie"]
?
Thank you
You do not need to change your file, but you cannot use it directly due to security issues. If I would write a Javascript which reads your secret files and you load my page, all your secrets would be revealed, therefore, if you want to load a file, you either have to allow your user to upload it and once the user uploads the file do your logic, or, you can request it via AJAX.
How to upload a file
An example for this is
<!DOCTYPE html>
<html>
<body onload="myFunction()">
<input type="file" id="myFile" multiple size="50" onchange="myFunction()">
<p id="demo"></p>
<script>
function myFunction(){
var x = document.getElementById("myFile");
var txt = "";
if ('files' in x) {
if (x.files.length == 0) {
txt = "Select one or more files.";
} else {
for (var i = 0; i < x.files.length; i++) {
txt += "<br><strong>" + (i+1) + ". file</strong><br>";
var file = x.files[i];
if ('name' in file) {
txt += "name: " + file.name + "<br>";
}
if ('size' in file) {
txt += "size: " + file.size + " bytes <br>";
}
}
}
}
else {
if (x.value == "") {
txt += "Select one or more files.";
} else {
txt += "The files property is not supported by your browser!";
txt += "<br>The path of the selected file: " + x.value; // If the browser does not support the files property, it will return the path of the selected file instead.
}
}
document.getElementById("demo").innerHTML = txt;
}
</script>
<p><strong>Tip:</strong> Use the Control or the Shift key to select multiple files.</p>
</body>
</html>
source: https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_fileupload_files
Getting the file via AJAX
In order to do that, you will need to:
send an AJAX request in your javascript code
parse the request and send back the file via PHP
do your logic in Javascript when the request is responded
Example:
HTML
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Download POST Request</title>
</head>
<body>
Enter a text and click the button: <input type="text" id="content" value="Text for the generated pdf">
<button id="download">Send AJAX Request and download file</button>
<script>
document.getElementById('download').addEventListener('click', function () {
var content = document.getElementById('content').value;
var request = new XMLHttpRequest();
request.open('POST', '../server/', true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.responseType = 'blob';
request.onload = function() {
// Only handle status code 200
if(request.status === 200) {
// Try to find out the filename from the content disposition `filename` value
var disposition = request.getResponseHeader('content-disposition');
var matches = /"([^"]*)"/.exec(disposition);
var filename = (matches != null && matches[1] ? matches[1] : 'file.pdf');
// The actual download
var blob = new Blob([request.response], { type: 'application/pdf' });
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
// some error handling should be done here...
};
request.send('content=' + content);
});
</script>
</body>
</html>
PHP
<?php
require_once 'vendor/autoload.php';
if($_SERVER['REQUEST_METHOD'] === 'POST') {
header('Content-type: application/pdf');
http_response_code(200);
// Contents
$pdfContent = !empty($_POST['content']) ? $_POST['content'] : 'no content specified';
// Generate the PDOF
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10, $pdfContent);
return $pdf->Output(null, 'foobar-' . time() . '.pdf');
}
// Bad method
http_response_code(405);
exit();
Source: https://nehalist.io/downloading-files-from-post-requests/
You will of course need to modify the code to comply to your needs. Reading a tutorial would not hurt.
you can use ajax for loading data from external file.
a sample of jquery get call is given below. You can also use the same code with your file path and variables.
$("button").click(function(){
$.get("demo_test.php", function(data, status){
alert("Data: " + data + "\nStatus: " + status);
});
});
if you are using pure java script instead of jQuery you have to use pure ajax calls.
for more details about jQuery ajax check this link

HTML+Javascript to read local file system

I am Java developer by birth with very limited hands on client side programming, so need help here.
I am basically looking for a way to create single page HTML/JavaScript application to read my local file system. I want to list directories and files within specific directory on my HTML page. What are the ways to achieve this.
Please note that I want to avoid server side coding or web application and stuff. Just need plain HTML and/or Javascript or any Javascript framework to do this for me. And I need it to be working primarily on chrome.
Please suggest.
Though its not a good to read the files at client side lot of security and access issues may occur. Still if you want you Can read the file at client side using filereader,check the following example:
<input type="file" id="fileinput" multiple />
<script type="text/javascript">
function readMultipleFiles(evt) {
//Retrieve all the files from the FileList object
var files = evt.target.files;
if (files) {
for (var i=0, f; f=files[i]; i++) {
var r = new FileReader();
r.onload = (function(f) {
return function(e) {
var contents = e.target.result;
console.log(contents);
alert( "Got the file.n"
+"name: " + f.name + "n"
+"type: " + f.type + "n"
+"size: " + f.size + " bytesn"
+ "starts with: " + contents.substr(1, contents.indexOf("n"))
);
};
})(f);
r.readAsText(f);
}
} else {
alert("Failed to load files");
}
}
document.getElementById('fileinput').addEventListener('change', readMultipleFiles, false);
</script>

Testing Ajax using localhost

I am trying to test a simple Ajax script using Javascript and I'm not receiving a response. The PHP script is placed in the htdocs folder of the local server and the HTML page that includes the Ajax calls is placed on my desktop. A readyState of 4 is received from the server but the status returned is 0, not 200.
The error generated on Firefox state:
NS_ERROR_DOM_BAD_URI: Access to restricted URI denied.
Here is the section of code responsible for calling the Ajax object:
var myRequest = getXMLHttpRequest();
function callAjax() {
var url = "localhost/clock.php";
var myRandom = parseInt(Math.random()*99999999);
myRequest. open("GET", url + "?rand=" + myRandom, true);
myRequest.onreadystatechange = responseAjax;
myRequest.send(null);
}
function responseAjax() {
if(myRequest.readyState == 4) {
if(myRequest.status == 200) {
var now = new Date();
var localTime = now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds();
var serverTime = myRequest.responseText;
document.getElementById("clock").innerHTML = "Server: " + serverTime + "<br />Local: " + localTime;
} else {
alert("An error has occurred: " + myRequest.statusText);
}
}
}
Can anyone offer insight to my problem?
OSX 10.8.5
MAMP version 2.1.3
You say your file is on the desktop. You cannot open a local file ( file:// ) and do ajax. You need to access the file through your Apache server ( http:// ).

Titanium HTTPCLIENT can't upload file

I try to use Brower can upload a file, but if I use Titanium upload, it doesn't work,
the brower code is
Brower upload file:
<form action="upload.php" method="post"
enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="Submit">
</form>
Upload.php file:
$tmp_file=$_FILES['file']['tmp_name'];
$target_file=basename($_FILES['file']['name']);
move_uploaded_file($tmp_file, "files/".$target_file);
my titanium code is:
var webaddress = 'http://' + address.value + ':' + port1.value + '/scanbatch/index.php';
xhr.open('POST',webaddress);
xhr.send({files : Titanium.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory,'scanbatch.txt')});
it can work but the webservice didn't received anything, just received a header.
and by the way , I can send out the short xml through the httpclient ,but if the xml be longer sometime it can't send out, more longer more fail,I mean not always, if the xml longer than 512KB, It always fail.
my code is
var webaddress = 'http://' + address.value + ':' + port1.value + '/liveho/scanbatch';
xhr.open('POST',webaddress);
xhr.send(xmlscript);
my onload function is
onload : function(e) {
alert(this.responseText);
},
please help me thank you
I will give you some advice, to narrow down the problem (Titanium side).
Have you tested if the path to the file is correct?
var file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory +
Ti.Filesystem.getSeparator() + 'scanbatch.txt');
if(file.size)
xhr.send({files : file});
else
Ti.API.info("File " + file.nativePath + " doesn't exist or is empty");
If it isn't the correct path, try to find it in the resourcesDirectory:
var file = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory +
Ti.Filesystem.getSeparator() + 'scanbatch.txt');
Your problem with disconnections might be diminish setting the timeout property. A onerror function could also help you find the problem. The onsendstream property will let you know the progression of the upload.
Ti.Network.createHTTPClient({
...
onload : function(e) {
alert(this.responseText);
},
onerror : function(e) {
Ti.API.debug(e.error);
alert(e.error);
},
onsendstream : function(e) {
var progress = parseFloat(e.progress)*100;
Ti.API.info("Upload progress:" + progress + "%");
//e.progress will contain a value from 0.0-1.0 with the progress of the upload
alert("Upload progress:" + progress + "%");
},
timeout : 5000 // in milliseconds
...
});

JavaScript: xmlhttprequest request and server answer

I'm starting off with js.
I want to fetch data from a server with xml. I wonder how to send a request as, and get an anser in xml through javascript functions.
It says I need a POST-Request and send an xml in the form:
<?xml version="1.0" encoding="UTF-8"?>
<ft>
<request clientId="123" apiName="api_search_location_stops_nearby" apiVersion="2.0">
<client clientId="123"/>
<requestType>api_search_location_stops_nearby</requestType>
<outputCoords>WGS84</outputCoords>
<fromCoordName>WGS84</fromCoordName>
<fromType>coords</fromType>
<fromWgs84Lat>48.22</fromWgs84Lat>
<fromWgs84Lon>16.39</fromWgs84Lon>
</request>
</ft>
To then get an xml answer. It has 2 or 3 nodes in it, which I'm interested in. From there on, it'll be no big deal.
It is all about a strange API from the vienna public transport company:
http://akirk.github.io/Wiener-Linien-API/
I basically want to get (open)data from them.
Here:
https://techscreen.tuwien.ac.at/node/794
I found a solution for php..
My try:
// Bare bones XML writer - no attributes
function xmlElement(name,content){
var xml
if (!content){
xml = '<' + name + '>' + '</' + name + '>'
}
else {
xml = '<'+ name + '>' + content + '</' + name + '>'
}
return xml
}
function sendRequest()
{
var xmlReq
xmlReq = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
xmlReq = xmlReq + "<ft>";
xmlReq = xmlReq + "<request clientId=\"123\" apiName=\"api_get_monitor\" apiVersion=\"2.0\">";
xmlReq = xmlReq + "<client clientId=\"123\"/>";
xmlReq = xmlReq + xmlElement("requestType", "api_get_monitor");
xmlReq = xmlReq + xmlElement("monitor",
xmlElement("outputCoords", "WGS84") +
xmlElement("type","stop") +
xmlElement("name","60201040") +
xmlElement("year","2013") +
xmlElement("month","10") +
xmlElement("day","3") +
xmlElement("hour","8") +
xmlElement("minute","0") +
xmlElement("line") +
xmlElement("sourceFrom","stoplist") );
xmlReq = xmlReq + "</request>" + "</ft>";
text1.text = xmlReq;
var xhr = new XMLHttpRequest();
xhr.onload = handleRequest;
xhr.open("POST", "http://webservice.qando.at/2.0/webservice.ft"); // POST or GET
xhr.send(xmlReq);
// xhr.responseXML // this is allways null
}
function handleRequest(answer)
{
console.log(answer.responseType);
console.log(answer.responseXML);
}
The core points of my question: On my code, should there be GET or POST? Is the request built up to fit the style above (or do I need linebreaks or convert to a DOM xml thing)? How does the recieving thing work. Am I doing this right? Should the variable answer then contain the xml with the answer?
This code is somehow not working. I printed the xml-string to the console and it looks just like above (without linebreaks). But the handleRequest function doesn't print anything (it is not called at all).
Thanks in advance!
Looks like it was good allready.
I got the wrong clientID. That was basically it. Then there was just a small modification to make:
xhr.onreadystatechange = function(){ page.handleRequest(xhr); }
..to send the xmlHttpRequest over to the function. This worked for me.

Categories

Resources