How to save json to a file using fetch() api? - fetch-api

index.html file placed in a folder and same folder has save.json file. Im running sublime text with server extension. Error: save.json 404 not found.
It can read from the same file but 404 when trying to write !
Pics below:
Code
Folder of index and save
console error
script below:
var OBJ = {
title: document.getElementById("title").innerHTML,
body: document.getElementById("body").innerHTML,
userId: document.getElementById("userid").innerHTML,
};
fetch('/save.json', {
method: 'POST',
body: JSON.stringify(OBJ),
headers: {
'Content-type': 'application/json; charset=UTF-8',
},
})
.then((response) => response.json())
.then((json) => console.log(json));

Related

Firebase hosting file upload via REST with Apps Script

I want to upload a file to Firebase hosting file upload via REST with Apps Script. Been trying to find a solution for days to no avail :( would highly appreciate any recommendations.
I'm following the official documentation here:
https://firebase.google.com/docs/reference/hosting/rest/v1beta1/sites.versions/populateFiles
And I can successfully get the upload URL using this code:
function getUploadURL() {
const YOUR_PROJECT_ID = 'sites/url-shortener-e42ec/versions/dd393a80797d713d';
let postUrl = 'https://firebasehosting.googleapis.com/v1beta1/YOUR_PROJECT_ID:populateFiles';
postUrl = postUrl.replace('YOUR_PROJECT_ID', YOUR_PROJECT_ID);
const options = {
method: 'post',
headers: {
Authorization: `Bearer ${ScriptApp.getOAuthToken()}`,
},
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(postUrl, options);
Logger.log(response);
}
which returns the following:
{
"uploadUrl": "https://upload-firebasehosting.googleapis.com/upload/sites/url-shortener-e42ec/versions/dd393a80797d713d/files"
}
And this is where I get kinda lost because I'm not quite sure on what to do next. The documentation says:
map (key: string, value: string)
A set of file paths to the hashes corresponding to assets that should be added to the version.
A file path to an empty hash will remove the path from the version.
Calculate a hash by Gzipping the file then taking the SHA256 hash of the newly compressed file.
But if I add a payload with a file hash to the call like so:
{
"files": {
"/teste": "3f0749957a1c4d91ed18b8e9df122709974e4e9c94c57f9245794c21dd76d4bd"
}
}
...then I get the error:
{
"error": {
"code": 400,
"message": "Precondition check failed.",
"status": "FAILED_PRECONDITION"
}
}
PART 2 :
The next issue I found is, now that I have the upload URL, I will need to actually upload the file, and according to their documentation I should:
Perform a multipart POST of the Gzipped file contents to the URL using a forward slash and the hash of the file appended to the end.
which I tried with the following apps script code:
function convert(hash) {
return hash.map(byte => ('0' + (byte & 0xFF).toString(16)).slice(-2)).join('');
}
function postFile() {
var files = DriveApp.getFilesByName('abc.txt');
let gzip;
let hash;
if (files.hasNext()) {
var file = files.next();
gzip = Utilities.gzip(file.getBlob());
hash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, gzip.getBytes());
}
let postUrl = 'https://upload-firebasehosting.googleapis.com/upload/sites/url-shortener-e42ec/versions/dd393a80797d713d/files/' + convert(hash);
/*
var textBlob = Utilities.newBlob("abc");
const gzip = Utilities.gzip(textBlob);
const hash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, gzipFile.getBytes());
*/
const data = {
"files": {
"/test.txt": convert(hash)
}
};
const options = {
method: 'post',
headers: {
Authorization: `Bearer ${ScriptApp.getOAuthToken()}`,
accept: 'application/json',
contentType: 'application/json'
},
muteHttpExceptions: true,
payload: JSON.stringify(data)
};
const response = UrlFetchApp.fetch(postUrl, options);
Logger.log(response);
}
... and get the following error:
Couldn't process request (status=412): File url-shortener-e42ec/dd393a80797d713d/0b3b82379e00a1994a46452e8cfd8b2c43ee8599f169a9ee4176253f1a8de469 can't be uploaded.
Appreciate all the help I can get. Thanks in advance!

Why the server responded with a status of 400

I am trying to create a sharepoint list using REST call. But i am getting error message: 'The server responded with a status of 400.'
Below is my code. Not able to understand where I am doing mistake:
url: https://abcTest.sharepoint.com/sites/dev/_api/web/lists.
digest: I am getting from a different function call.
const response = await fetch(url, {
method: 'POST',
credentials: 'include',
headers: {
'Accept': 'application/json;odata=verbose',
'Content-Type': 'application/json;odata=nometadata',
'X-RequestDigest': digest
},
body: JSON.stringify({
__metadata: {
type: 'SP.List`
},
AllowContentTyes: true,
BaseTemplate: 100,
ContentTypesEnabled: true,
Description: 'List description',
Title: 'MyList'
})
});
I think you should change
Accept: 'application/json;odata=verbose'
===> 'Accept': 'application/json;odata=verbose'
And : method: 'POST'` ===> method: 'POST'
Make sure parameter is json data.

WebKitFormBoundary uploading a file to S3 using axios FormData

I am trying to upload files to S3, files are successfully uploaded and but when downloaded it contains WebKitFormBoundary
------WebKitFormBoundaryrTBzWaHQntWAtZLX
Content-Disposition: form-data; name="file"
hello world
------WebKitFormBoundaryrTBzWaHQntWAtZLX--
Upload using axios
const formData = new FormData();
formData.append('file', this.file);
this.axios.put(this.formUrl,
formData,
{
headers: {
// 'Content-Type': `multipart/form-data`,
'Content-Type' : 'application/octet-stream',
},
})
.then((res) => {
console.log(res)
}).catch((e) => {
console.error(e)
});
How do I remove boundary
I faced the same issue. But the solution is simple. Here is my code I used to upload the file
axios({
method: "PUT",
url: url,
data: fileToUpload, // NOTE - this is the file not the FormData Object
headers: {
"Content-Type": "multipart/form-data" }
})
.then(res => {
this.setState({
uploadSuccess: "File upload successfull",
error: undefined
});
})
.catch(err => {
console.log(err)
});
What really happens is when you attach the file to FormData the FormData get serialized and that serialized data is stored in S3. That's why the file become corrupted.
In the solution we don't wrap the file inside a FormData object. What we do is we directly add the file to data attribute. So nothing other than the file itself get serialized and stored in S3.
Hope this answer would help

Groovy wslite.rest.RestClient post or put results in a 411 Length Required Error

Using the wslite.rest.RestClient, if I use post or put, I'm getting a 411 Length Required error returned from the service. I've added the header Content-Length: (size) but I still get an error. Does anyone have suguestions? Here's the code for a put request:
def builder = new JsonBuilder()
// required json data
def root = builder {
"ActivationDate" "\\/Date(1434563608000-0500)\\/"
"EmailAddress" "ebaa#gmail.com"
"ExpirationDate" "\\/Date(1435686808000-0500)\\/"
"FirstName" "ebaa"
"LastName" "ebaa"
"MiddleName" "ebaa"
"OtherName" "ebaa"
"Password" "abc12345"
"Status" 1
}
RESTClient restClient = new RESTClient('https://serviceBaseUrl')
Response response
try {
restClient.authorization = new HTTPBasicAuthorization(username: 'user', password: 'pass')
restClient.defaultCharset = 'UTF-8'
restClient.defaultContentTypeHeader = 'application/json'
restClient.defaultAcceptHeader = 'application/json'
response = restClient.put(path: "/Location/${locName}/Administrator/${name}",
headers:['Accept': 'application/json',
'Accept-Language':'en-US,en;q=0.5', 'Content-Type': 'application/json; charset=UTF-8',
'Connection':'keep-alive', 'Pragma':'no-cache', 'Cache-Control':'no-cache',
'Content-Length': builder.toString().length()],
data: builder.toPrettyString().getBytes())
return response.json
} catch(ex) {
ex.printStackTrace()
}
I've also tried changing the data: param to body, but I get the same response. Also, If I use the Firefox plugin, HttpRequester (https://addons.mozilla.org/En-us/firefox/addon/httprequester/) and make the same request, I get a 200 status code and the appropriate data is updated. Thanks!
For put or post it is expecting the payload to be in a closure. Try the following, this should send the data and automatically set the right Content-Length:
....
....
response = restClient.put(
path: "/Location/${locName}/Administrator/${name}",
headers:['Accept': 'application/json',
'Accept-Language':'en-US,en;q=0.5',
'Content-Type': 'application/json; charset=UTF-8',
'Connection':'keep-alive',
'Pragma':'no-cache',
'Cache-Control':'no-cache'])
{
text builder.toPrettyString()
//bytes builder.toPrettyString().bytes // or as bytes
//json 'ActivationDate': '...', 'EmailAddress': '...' // or a json string from a map
}
See the Sending Content section of the README.

Google Docs API: cannot set document title

I am trying to upload a file using Node and Google Docs REST API. I can upload the file just fine if I don't include the metadata, but it will always be uploaded as 'Untitled'.
But when I include the meta data I get the following error after sending my atom data and attempting to continue with the file upload:
ParseException - Content is not allowed in prolog
This is my first request to create an upload session and get a resumable-media-link
var meta = '<?xml version="1.0" encoding="UTF-8"?>'
meta+= '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:docs="http://schemas.google.com/docs/2007">'
meta+= '<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/docs/2007#document"/>'
meta+= '<title>Test</title></entry>'
var options = {
host: 'docs.google.com',
path: '/feeds/upload/create-session/default/private/full',
method: 'POST',
headers: {
'Host' : 'docs.google.com',
'Content-Length' : meta.length,
'Content-Type': 'application/atom+xml',
'GData-Version' : 3,
'Authorization' : 'GoogleLogin auth=' + authToken,
'X-Upload-Content-Type' : 'application/msword',
'X-Upload-Content-Length' : 31232
}
}
var req = https.request(options, function (res) {
// make 2nd request
});
req.end(meta);
This is what my 2nd request looks like after getting the resumable-media-link
var options = {
host: 'docs.google.com',
path: resumableMediaLink,
method: 'PUT',
headers: {
'Content-Length': data.length,
'Content-Type': 'application/msword',
'Content-Range': 'bytes 0-' + (data.length-1) +'/'+ data.length
}
}
var req = https.request(options, function (res) {
res.on('data', function (chunk) {
// ...
});
});
req.write(data);
req.end();
It seems like I am sending the atom data incorrectly. Any ideas of what I could be doing wrong?
I figured out what I was doing wrong.
I needed to set the 'Slug' header in the first POST request to initiate a resumable session.
I had it in the following request.