So I am trying to check if a pdf file exists on my server or not.
PDF files are named in korean like abc.com/토보토보.pdf
I have tried :
function UrlExists(url)
{
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
console.log(http.status);
}
But the problem is it always encoded to example.com/%C3%AD%C2%86%C2%A0%C3%AB%C2%B3%C2%B4%C3%AD%C2%86%C2%A0%C3%AB%C2%B3%C2%B4.pdf
UrlExists("example.com/토보토보.pdf")
01:51:29.144 VM428:14
HEAD
http://example.com/%ED%86%A0%EB%B3%B4%ED%86%A0%EB%B3%B4.pdf
404 (Not Found)
How do i get the solution to my problem?
I think maybe you want to run the base filename part of your url through encodeURIComponent before sending the http request out.
This should convert your korean text to the escaped text (with the percentage signs) and then it can find it.
source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
try window.encodeURI or window.encodeURIComponent:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
// encodes characters such as ?,=,/,&,:
console.log(encodeURIComponent('?x=шеллы'));
// expected output: "%3Fx%3D%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"
console.log(encodeURIComponent('?x=test'));
// expected output: "%3Fx%3Dtest"
or try this:
const pdf = {name:"토보토보"};
fetch(url, {
method: 'POST',
body: JSON.stringify(pdf),
headers: new Headers({
'Content-Type': 'application/json'
})
})
.then(function(res){
return res.json()
})
.then(function(v){
// read the result
})
or you could do a GET request by putting JSON as a query param:
const pdf = {name:"토보토보"};
const url = "example.com?pdf=${JSON.stringify(pdf)}"
fetch(url).then(...);
Related
I've a got a function in my web api 2.0 to download a file but hadn't tried it in a while and only discovered yesterday that it was no longer working. I've partially fixed the issue with createObjectURL but one thing I've noticed is that while the Content-Disposition is set in my web api:
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = new HttpResponseMessage();
var filename = this.Document.GetFilename();
var mimeType = MimeMapping.GetMimeMapping(filename);
response.Content = new StreamContent(new MemoryStream(this.Document.ToData()));
response.Content.Headers.ContentLength = this.Document.Data.Length;
response.Content.Headers.ContentType = new MediaTypeHeaderValue(mimeType);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = filename
};
return Task.FromResult(response);
}
Yet when I check it in JavaScript, it always null from the response header:
success: function (blob, status, xhr) {
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
...
}
Any ideas why?
Thanks.
UPDATE-1:
The content disposition appears to be returned when I check the response in the Network section of the browser but when I call xhr.getAllResponseHeaders() or xhr.getResponseHeader('Content-Disposition');, it is not returned by either function calls as you can see in the snapshot below:
I just figured out the problem and it was of my own doing unfortunately!!
I had the following in my ajax request:
xhrFields: {
responseType: 'blob'
}
but then I introduced credentials support and introduce this
xhrFields: {
withCredentials: true
}
but I didn't spot this until this morning when I realized I stupidly declared as above clearly i.e. 2 statements, thus, overwriting the responseType: 'blob' setting when I should have declared it as:
xhrFields: {
responseType: 'blob',
withCredentials: true
}
From server side, please set this header in response "Access-Control-Expose-Headers” with value “*” to make all headers in response to be read by frontend script. Or just set “Content-Disposition” for this case, instead of *, to only allow reading value of content-disposition header by frontend script.
I am trying to upload file from Apex to Sharepoint but getting error as '400 Bad Request'.But work from JS CODE. Following is my code snippet :
Apex Code
Http http = new Http();
HttpRequest httpRequestToSend = new HttpRequest();
httpRequestToSend.setEndpoint('https://sample.sharepoint.com/sites/siteName/_api/web/GetFolderByServerRelativeUrl(\''+'/sites/siteName/Shared Documents'+'\')/Files/Add(url=\''+'document3.txt'+'\', overwrite=true)');
httpRequestToSend.setMethod('POST');
httpRequestToSend.setHeader('Authorization', 'Bearer ' + token);
httpRequestToSend.setHeader('Content-Type','application/json; odata=verbose');
httpRequestToSend.setBodyAsBlob(Blob.ValueOf('test Message'));
System.debug('***** httpRequestToSend-->' + httpRequestToSend);
Http http1 = new Http();
HttpResponse httpResponse1 = http1.send(httpRequestToSend);
System.debug('***** httpResponse-->' + httpResponse1.toString());
System.debug(httpResponse1.getBody());
JS CODE
var myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer " + Token);
myHeaders.append("Content-Type", "application/json;odata=verbose");
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: fileBuffer,
};
fetch('https://sample.sharepoint.com/sites/siteName/_api/web/GetFolderByServerRelativeUrl(\'/sites/siteName/Shared Documents\')/Files/Add(url=\'test.txt\', overwrite=true)', requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => alert('error', error));
}
Thankyou
As per the documentation salesforce can't communicate to FTP directly that means can't Read/Write file at FTP Server.
I also faced this issue and this is how I resolved it:-
Step1: Create & host an External API on in any language(C#, Python) that takes two parameters one as fileName and the other one as fileData and uploads that file.
Step2: At Salesforce end, consume that API using HttpRequest and pass your file as filedata and fileName.
public void uploadFileToFTP_Service(string fileName,string fileData)
{
string value='{"fileName":"'+fileName+'","fileData": "'+fileData+'"}';
HttpRequest req = new HttpRequest();
req.setEndpoint('http://yourhostedApIPath:9001/data');
req.setMethod('POST');
req.setTimeout(120000);
req.setHeader('content-type','application/json; charset=utf-8');
req.setBody(value);
Http http = new Http();
HttpResponse res = http.send(req);
system.debug('Status code: ' + res.getStatusCode());
}
I was beating my head on this for some time today, and was finally able to get past the "400 Bad Request" error by escaping the space characters in my relative url path (I expect the filename may need the same workaround).
Each space character (" ") must be replaced with the ASCII reference "%20"
so in your example, the endpoint url:
'https://sample.sharepoint.com/sites/siteName/_api/web/GetFolderByServerRelativeUrl(\'/sites/siteName/Shared Documents\')/Files/Add(url=\'test.txt\', overwrite=true)'
should be changed to:
'https://sample.sharepoint.com/sites/siteName/_api/web/GetFolderByServerRelativeUrl(\'/sites/siteName/Shared%20Documents\')/Files/Add(url=\'test.txt\', overwrite=true)'
At least in my case, this corrected the issue.
I have a REST API (POST method) which returns the content of a PDF. I tested using curl and I do can see and open the file on my computer:
curl http://localhost:8080/ponyapp/test/generate-pdf -H 'Content-Type: application/json' -d '[{"fieldA":"valueA", "fieldB":"valueB", ...}]' -i -o ~/Desktop/label.pdf
Now I have a vuejs/js application which needs to use this REST API and be able to save the file into the local computer. My approach (please correct me if I am wrong) is:
call the API to get the response payload
put the payload into a file
download the file into the local computer by using HTML anchor element
For some reason, this is not working
This the response payload:
%PDF-1.4↵%����↵1 0
obj↵<<↵/CreationDate(D:20200301141435+13'00')↵/Title(CourierPost
Label)↵/Creator(PDFsharp 1.50.4000-wpf
(www.pdfsharp.com))↵/Producer(PDFsharp 1.50.4000-wpf
(www.pdfsharp.com))↵>>↵endobj↵2 0 obj↵<<↵/Type/Catalo...
I have tried different variations of this code:
axios
.post(
this.$store.state.baseUrl + "test/generate-pdf",
[this.uberShipment],
{
responseType: "blob",
headers: {
Authorization: "Bearer " + this.getToken()
}
}
)
.then(response => {
let filename = "label" + new Date().toISOString() + ".pdf";
let data = new Blob(response.data, { type: 'application/pdf,' });
let link = document.createElement("a");
link.setAttribute("href", (window.webkitURL || window.URL).createObjectURL(data));
link.setAttribute("download", filename);
link.click();
})
.catch(error => {
...
})
Which fails with the error below:
error = TypeError: Failed to construct 'Blob': The provided value
cannot be converted to a sequence. at eval
(webpack-internal:///./node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/vuetify-loader/lib/loader.js?!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/components/CreateShipmentAndNZPostDomesticLabel.vue?vue&type=script&lang=js&:604:20)
_this
I would appreciate any advice of why this is not working (either in my approach or in the code)
thank you
You must pass an array to blob constructor
let data = new Blob([response.data], { type: 'application/pdf,' });
Docs
I am attempting to send the user an alert when an empty file is downloaded (the server sends back the number 0 when this is the case:
$http.get(service)
.success(function (response) {
if (response === parseInt(response, 10)) {
alert("That query had no results");
$("#dialog").dialog("close");
}
else {
var blob = new Blob([response], { type: "application/vnd.ms-excel" });
var objectUrl = URL.createObjectURL(blob);
$("#dialog").dialog("close");
window.location = objectUrl;
}
});
The file is downloading fine but when I go to open it, I get a "file formatted incorrectly message" from excel. I know that the excel file is coming down alright because this:
window.location = service
works just fine.
I have tried both:
application/vnd.ms-excel
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
file types. Neither one works. Thanks in advance.
edit: I thought that perhaps I needed to get the raw response (for this angular $http service) so I tried:
http.get(service, {
transformResponse:
function (d, h) {
return d;
}
})
.success(function (response) {
..same as above
});
Still not working though. In fact, I put a break point on d, it looks like a lot of the "unrecognized" characters are being changed to question marks (I compared d to my network tab.) In the network tab, the characters are one way but when I check d they have been changed to question marks.
The response returned from the $http.get is an object that includes the headers and you can't form a blob from it directly. You can access the binary content returned by the service like this:
var blob = new Blob([response.data], { type: "application/vnd.ms-excel" });
I'm converting powerpoint files to individual images, and the images that are produced end up corrupted when I upload from Node.
The npm modules I'm using are request and node-form-data.
I upload a file from my Node app like this:
var request = require('request');
var FormData = require('form-data');
function processPresentation(fileName,fileLoc,userId,customerId){
var data = new FormData();
data.append('my_file',fs.createReadStream(fileLoc));
var options = {
url: config.getConverter()+"?tenant="+customerId+"&author="+userId+"&name="+fileName+"&ext=ppt",
method: 'POST',
form:data,
headers:{'x-auth-token':token,'Content-Type':'application/vnd.openxmlformats-officedocument.presentationml.presentation'}
};
request.post(options,function(error,response,body){
console.log(body);
if(error){
console.log('error',error);
}
if(!response){
}
if(response.statusCode === 200){
addPresentation(JSON.parse(body),userId);
}
});
}
And it goes through my conversion process, I get a file like this as output:
Here's what all this actually says, if you open the powerpoint file and look at the text:
http://pastebin.com/Dbh0JPKA
When I use Postman and upload the same file like this:
POST HTTP/1.1
Host: xxxx.xxxxxxxxxx.net?name=00a94ec9-8f70-4279-8972-f49935cda295&ext=ppt&tenant=543840f80019abda4937a9e2&author=543bef549f8d54a53a02f6d9
Content-Type: application/vnd.openxmlformats-officedocument.presentationml.presentation
x-auth-token: 772a5c0c023a447f68a9ac4fb2bb4bd39bafeb16b753df2222ffc835750cbbe6a4ef9ee82fab0902f39bc26851016a873d44c91a64f67de5e10044ef0787cebe
Cache-Control: no-cache
Postman-Token: 74aff430-f6b8-c7cd-d477-b9cc35897bb7
undefined
I get output like this:
Which is what I want.
Ok, I think that the problem is that you are sending mime/multipart encoded data and you just want to send the file as the raw body of the post. There are a couple ways to do this.
Option #1, Stream the File:
var options = {
url: config.getConverter()+"?tenant="+customerId+"&author="+userId+"&name="+fileName+"&ext=ppt",
headers:{'x-auth-token':token,'Content-Type':'application/vnd.openxmlformats-officedocument.presentationml.presentation'}
};
fs.createReadStream(fileLoc).pipe(request.post(options));
This technique is actually streaming the file as the raw post body for your request.
Option #2, Read the File then Post:
var options = {
url: config.getConverter()+"?tenant="+customerId+"&author="+userId+"&name="+fileName+"&ext=ppt",
headers:{'x-auth-token':token,'Content-Type':'application/vnd.openxmlformats-officedocument.presentationml.presentation'},
body: fs.readFileSync(fileLoc)
};
request.post(options, callback);
Here you are reading the file into a string and posting it using the body option. This sets the post body raw rather than using a mime/multipart encoding as you get with formData.
Try dropping the require for form-data and just do this:
var options = {
url: config.getConverter()+"?tenant="+customerId+"&author="+userId+"&name="+fileName+"&ext=ppt",
method: 'POST',
formData: {
my_file: fs.createReadStream(fileLoc)
},
headers:{'x-auth-token':token,'Content-Type':'application/vnd.openxmlformats-officedocument.presentationml.presentation'}
};
Important there is formData vs form
Doing this fixed it:
var length = fs.statSync(fileLoc).size;
console.log('length is',length);
var req = request.post({uri: config.getConverter()+"?tenant="+customerId+"&author="+userId+"&name="+fileName+"&ext=ppt",
headers:{
'x-auth-token':token,
'Content-Type':'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'content-length':length
}
});
fs.createReadStream(fileLoc).pipe(req).pipe(process.stdout);