Match a curl request to NancyFx service from browser js - javascript

I've got a microservice (in NancyFx) that works as expected for the following cURL command:
curl --verbose --form file=#"C:\test\image.png" http://localhost:8080/file/upload
The file shows up inside Nancy as expected at:
context.Request.Files[0] //The file bytes are here, yeah!!
Now I've got to get my web-client to send a selected file to the same service, in the same way.
TLDR; You can skip my failure examples below if you'd like
I've tried several versions of the following with no success:
var uploadForm = new FormData();
// Add the file to the request.
uploadForm.append("file", file, name);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:8080/file/upload', true);
xhr.onload = function() {
if (xhr.status === 200)
alert('File ' + name + 'Upload successfully!!!');
else errorFn("Upload Failure on file " + name);
};
//Send the data
xhr.send(uploadForm);
and several versions of the following, also with no success:
var postConfig = {
url: 'http://localhost:8080/file/upload',
data: uploadForm,
processData: false, //tries without this as well
type: "POST",
dataType: "application/x-www-form-urlencoded; charset=UTF-8",
cache: false,
success: successFn,
error: errorFn
}
$.ajax(postConfig);
I've tried the above with
file = direct reference to $('MyFileSelectorControl').files[0]
file being set with the following code:
var reader = new FileReader();
reader.onload = function (result) {
var fileContent = new Uint8Array(result.target.result);
var encContent = new SP.Base64EncodedByteArray();
for (var b = 0; b < fileContent.length; b++) {
encContent.append(fileContent[b]);
}
<Set file = encContent and send AJAZ as above>
};
reader.readAsArrayBuffer(fileInput);
Setting file = to fileContent above (IOW, after it has been through the reader, but not encoded.)
How do I submit this file from javascript (jQuery or standard) so that it works like it does from cURL?

Here is the code that finally worked. (Admittedly, I had thought I had already tried this and said so in my question)
var file = $('MyFileSelectorControl').files[0];
var uploadForm = new FormData();
// Add the file to the request.
uploadForm.append("file", file, name);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:8080/file/upload', true);
xhr.onload = function() {
if (xhr.status === 200)
alert('File ' + name + 'Upload successfully!!!');
else errorFn("Upload Failure on file " + name);
};
//Send the data
xhr.send(uploadForm);

Related

SharePoint REST Query returns 403 forbidden error

I'm trying to upload a file to the SharePoint directory using the REST API and the JQuery.
Reference: https://learn.microsoft.com/en-us/sharepoint/dev/sp-add-ins/upload-a-file-by-using-the-rest-api-and-jquery
I'm trying to run the below code from the chrome browser console.
var CreateNewList = function() {
var fileName = "test1.txt";
var reader = new FileReader();
var arrayBuffer = reader.result;
var serverUrl = "https://{site}.sharepoint.com/";
var serverRelativeUrlToFolder = 'SampleDocuments/Folder1';
// Construct the endpoint.
var fileCollectionEndpoint = String.format(
"{0}/_api/web/getfolderbyserverrelativeurl('{1}')/files" +
"/add(overwrite=true, url='{2}')",
serverUrl, serverRelativeUrlToFolder, fileName);
return jQuery.ajax({
url: fileCollectionEndpoint,
type: "POST",
data: arrayBuffer,
processData: false,
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": jQuery("#__REQUESTDIGEST").val()
}
});
};
String.format = function() {
var s = arguments[0];
for (var i = 0; i < arguments.length - 1; i += 1) {
var reg = new RegExp('\\{' + i + '\\}', 'gm');
s = s.replace(reg, arguments[i + 1]);
}
return s;
};
The above code works fine when I run this on the SharePoint page. But the same code doesn't work when I tried from a different Web page which means the code works fine on the same domain but not on the different domain.
So, tried the other example (example 1 from the above-mentioned URL) which is to upload files across the domain.
function addFileToFolder() {
var fileName = "test1.txt";
var reader = new FileReader();
var arrayBuffer = reader.result;
var serverRelativeUrlToFolder = 'SampleDocuments/Folder1';
var appWebUrl = "https://{site}.sharepoint.com";
var hostWebUrl = "https://{site}.sharepoint.com";
var fileCollectionEndpoint = String.format(
"{0}/_api/sp.appcontextsite(#target)/web/getfolderbyserverrelativeurl('{1}')/files" +
"/add(overwrite=true, url='{2}')?#target='{3}'",
appWebUrl, serverRelativeUrlToFolder, fileName, hostWebUrl);
return jQuery.ajax({
url: fileCollectionEndpoint,
type: "POST",
data: arrayBuffer,
processData: false,
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": jQuery("#__REQUESTDIGEST").val()
}
});
}
This code doesn't work in any domain (failed in both SharePoint page and other pages) and returns 403 Forbidden error:
error:
code: "-2147024891, System.UnauthorizedAccessException"
message:
lang: "en-US"
value: "Access denied. You do not have permission to perform this action or access this resource."
I tried to get appWebUrl and hostWebUrl from the below methods, but the returned value is undefined, so just hardcoded these values in the code.
// Get the add-in web and host web URLs.
appWebUrl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));
hostWebUrl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
function getQueryStringParameter(paramToRetrieve) {
var params =
document.URL.split("?")[1].split("&");
var strParams = "";
for (var i = 0; i < params.length; i = i + 1) {
var singleParam = params[i].split("=");
if (singleParam[0] == paramToRetrieve)
return singleParam[1];
}
}
Can anyone help me to resolve this issue?
You need know the api scenario how to use it.
The rest api works in SharePoint pages as the request will use current user authentication to access SharePoint, it won't work in a different domain page as there is no authentication.
SPAppWebUrl/SPHostUrl used in SharePoint add-in solution.
You have to follow the authentication flow to authenticate your request to access SharePoint from a different application.
https://www.c-sharpcorner.com/article/access-sharepoint-online-rest-api-via-postman-with-user-context/

Downloaded tar file is not opening in node js.?

I am trying to download the tar file using node js , file is saving but not able to open that file I have tried the following code
var fs = require("fs");
var fn = "version1.tgz";
var request = require('request');
var downloadUrl = "https://url/api/download?downloadFile="+fn+"&username=mkhun";
request({
url: downloadUrl,
method: 'POST',
}, function (err, resp, body) {
var rmv = body;
console.log(rmv);
fs.writeFile(fn,rmv,function(err,data){
console.log(err);
});
});
but the same thing is working with javascript ajax
var fn = "version1.tgz";
var xhttp = new XMLHttpRequest();
var downloadUrl = "https://url/api/download?downloadFile="+fn+"&username=mkhun";
console.log(downloadUrl);
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var blob = this.response;
var fileName = fn;
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download=fileName;
link.click();
} else if(this.readyState == 2) {
xhttp.responseType = "blob";
}
};
xhttp.open("POST", downloadUrl , true);
xhttp.send();
I don't know how to fix the issue in node-red
This is an issue of encoding when receiving request data.
You can use streams to pipe the request into the filesystem directly from a Buffer. Otherwise, you can use encoding: null in the request options
request({
url: downloadUrl,
method: 'POST',
encoding: null
}, ...)

Does anyone one know how to translate this jQuery into normal js?

So i have an email sending function on my cordova app and it uses jQuery to do it. When debugging my app the ajax function works fine when testing in my browser, but when i build the app and test it on my phone it does not work. I had another problem like this that was only fixed once i used normal js instead of jQuery. Here is the function:
var message = localStorage.getItem("Message");
var key = "dJdJekCVAFIqvUJ13DEczZjgIh_4MyeIGEHz2GBYKFe"; // <<KEY
var message_name = "defender_send_message"; // <<MESSAGE NAME
var url = "https://maker.ifttt.com/trigger/" + message_name + "/with/key/" + key;
$.ajax({ // <<SEND
url: url,
data: {value1: message,
value2: localStorage.getItem("AdminsEmail")},
dataType: "jsonp",
complete: function(jqXHR, textStatus) {
console.log("Message Sent");
}
});
Does anyone know how to translate it into normal js? Thank you
You need to use XMLHttpRequest object to make a ajax call using vanilla JS.
var message = localStorage.getItem("Message");
var key = "dJdJekCVAFIqvUJ13DEczZjgIh_4MyeIGEHz2GBYKFe";
var message_name = "defender_send_message";
var url = "https://maker.ifttt.com/trigger/" + message_name + "/with/key/" + key;
var data = {};
data.value1 = message;
data.value2 = localStorage.getItem("AdminsEmail");
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status == 200) {
console.log("Message Sent");
}
}
}
xmlhttp.open('POST', url, true);
xmlhttp.responseType = 'jsonp';
xmlhttp.send(data);

handling csv response in backbonejs

I am posting some data to server through Backbone.js and server sends a csv file as response. As Backbone.js handles only json format can some body tell me how to handle this case, so that i would be able to download the csv file gracefully.
object = {};
object.c1 = formObj.c1
hash = {
success: function(model, response, options) {
},
error: function(model, response, options) {
return console.log(response);
}
};
model = new P.models.mine(object);
model.doSomething(object, hash);
It always comes to error part.
The ideal way to handle this would be to change your back end code to return JSON, or create another route that returns JSON. Since you are asking this question I'm assuming that isn't an option for you.
Basically you are going to have to parse the CSV on the client side:
https://stackoverflow.com/a/1293163/944006 - Should get you started.
If you are asking to download a csv file, then just pointing the browser at the location should prompt the user for download. You cannot prompt a file download through ajax(for good reason), but there are ways to tiptoe around this limitation:
https://stackoverflow.com/a/9970672/944006
You could also use plain javascript rather than Backbone.js. Believe me this is the best way.
Here is some code:
var xhr = new XMLHttpRequest();
xhr.open('POST', Urls.download, true);
xhr.responseType = 'blob';
xhr.setRequestHeader("Authorization", "Bearer " + access_token);
xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8');
xhr.onload = function (e) {
if (this.status == 200) {
var blob = new Blob([this.response], { type: 'application/vnd.ms-excel' });
var downloadUrl = URL.createObjectURL(blob);
var a = document.createElement("a");
a.id = "a" + new Date().getTime();
a.setAttribute("data-bypass", "");
a.href = downloadUrl;
a.download = "list_" + new Date().getTime() + ".xlsx";
document.body.appendChild(a);
a.click();
} else {
alert('Unable to download excel.')
}
};
xhr.send(JSON.stringify(this.obj));

Download Binary Data as a File Via Javascript

I'm making an ajax call to an API that returns binary data. I'm wondering if its possible to take that binary data and display it for the client in a new window? This is what I'm doing right now. The problem is, the document opens up, but its completely blank.
$.ajax({
type: "POST",
url: apiURL,
data: xmlRequest,
complete: function(xhr, status) {
var bb = new window.WebKitBlobBuilder();
// Append the binary data to the blob
bb.append(xhr.responseText);
var blobURL = window.webkitURL.createObjectURL(bb.getBlob('application/pdf'));
window.open(blobURL);
}
});
Any ideas?
Okay, I figured it out. I had to specify the responseType as 'array buffer':
function downloadPDF() {
var xhr = new XMLHttpRequest();
xhr.open('POST', API_URL, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
if (this.status == 200) {
var bb = new window.WebKitBlobBuilder();
bb.append(this.response); // Note: not xhr.responseText
var blob = bb.getBlob('application/pdf');
var blobURL = window.webkitURL.createObjectURL(blob);
window.open(blobURL);
}
};
xhr.send(createRequest());
}

Categories

Resources