I'm trying to download a file from google drive, but I get a 405 Method not allowed
I have a valid token and I can upload a file, but downloading it using the fileId from the upload doesn't work. What am I doing wrong?
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/upload/drive/v3/files/'+fileId);
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.onload = () => {
console.log(JSON.stringify(xhr.response,true,4));
};
xhr.send();
I believe your goal and situation as follows.
You want to download a file from Google Drive.
Your access token can be used for downloading the file from Google Drive using Drive API.
For this, I would like to propose the following modification.
Modification points:
I think that in your script, the endpoint of 'https://www.googleapis.com/upload/drive/v3/files/'+fileId cannot be used for downloading the file from Google Drive.
At Google Drive API, the method for downloading the file is different between Google Docs and others. Google Docs files are Google Document, Google Spreadsheet, Google Slides and so on.
From your question, I couldn't understand about the file type you want to download. So in this answer, I would like to propose the following 2 patterns.
Pattern 1:
When fileId is NOT Google Docs file, you can use the following script. The method of Files: get in Drive API is used. In this case, if the file of file ID is the text file, you can see the file content in the console.
Modified script:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/drive/v3/files/' + fileId + '?alt=media');
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.onload = () => {
console.log(JSON.stringify(xhr.response,true,4));
};
xhr.send();
Pattern 2:
When fileId is the Google Docs file which are Google Document, Google Spreadsheet, Google Slides and so on, you can use the following script. The method of Files: export in Drive API is used.
Modified script:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/drive/v3/files/' + fileId + '/export?mimeType=application%2Fpdf');
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.onload = () => {
console.log(JSON.stringify(xhr.response,true,4));
};
xhr.send();
In this case, the Google Docs file is downloaded as a PDF format. When you want to download the file as other mimeType, please set the mimeType.
Note:
In above scripts, the file is downloaded as the binary.
References:
Download files
Files: get
Files: export
Related
This question has been asked before, but the answer was using API V2. The google documentation does not clarify how to create a file with its content using javascript client code. I tried using the code listed under Node, however, it only creates the file, it does not insert any content. Here is my code:
let fileMetadata = {
'name': name,
parents: [parentId]
};
let media = {
mimeType: 'text/plain',
body: 'content inside file'
};
gapi.client.drive.files.create({
resource: fileMetadata,
media,
fields: 'id'
})
.then(response => {
console.log('response: ', response);
})
.catch(() => {
console.log('something is wrong');
});
Can someone help me insert content into files please?
How about this sample script? In my environment, although gapi.client.drive.files.create() can create an empty file on Google Drive, it cannot directly upload files including contents. I think that this might not be able to upload files and metadata with the multipart/related, although this might be resolved by the future update. So now, as one of workarounds, I use XMLHttpRequest.
Before you use this sample script, please confirm the following points.
In your situation, you have already been able to create files using gapi. In my script, the access token is retrieved using gapi.
When you use this script, please set fileContent and metadata.
Sample script :
In this sample script, a text file including contents is created under a folder.
var fileContent = 'sample text'; // As a sample, upload a text file.
var file = new Blob([fileContent], {type: 'text/plain'});
var metadata = {
'name': 'sampleName', // Filename at Google Drive
'mimeType': 'text/plain', // mimeType at Google Drive
'parents': ['### folder ID ###'], // Folder ID at Google Drive
};
var accessToken = gapi.auth.getToken().access_token; // Here gapi is used for retrieving the access token.
var form = new FormData();
form.append('metadata', new Blob([JSON.stringify(metadata)], {type: 'application/json'}));
form.append('file', file);
var xhr = new XMLHttpRequest();
xhr.open('post', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id');
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
xhr.responseType = 'json';
xhr.onload = () => {
console.log(xhr.response.id); // Retrieve uploaded file ID.
};
xhr.send(form);
Request body :
In this script, form is as follows. This is sent to Google Drive using the create method of Drive API.
------WebKitFormBoundaryxX0XmxgooMjdUECR
Content-Disposition: form-data; name="metadata"; filename="blob"
Content-Type: application/json
{"name":"sampleName","mimeType":"text/plain","parents":["#####"]}
------WebKitFormBoundaryxX0XmxgooMjdUECR
Content-Disposition: form-data; name="file"; filename="blob"
Content-Type: text/plain
sample text
------WebKitFormBoundaryxX0XmxgooMjdUECR--
In my environment, I confirmed that this works fine. But if this didn't work in your environment, I'm sorry.
I am fetching a file from Google Drive using Picker API. I have successfully got file data from downloadUrl:
var xhr = new XMLHttpRequest();
xhr.open('GET', file.downloadUrl);
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
xhr.onload = function () {
fileRecievedCallback(xhr.responseText, doc.name);
};
I have file data in xhr.responseText, Now I want to send this byte string to .Net Web api and convert that to file and save to disc. I can send this file data to web api. Question is how do I read this byte string in C# and convert it to file and save to disk?
I'm piecing together tutorials from the web to be able to build a tool where users can upload images offline in an HTML5 app to filesystem storage along with some personal details and when they are online, they can "sync" which uploads the files and their details to the server.
I've managed to get a simple page up that stores images in file storage & sizes them down but I am unable to figure out how to post them using XMLHttpRequest. I've managed to push just the file data and store it one by one by using php://input (taken from Upload file from HTML5 Filesystem by XMLHttpRequest) but I need it to be uploaded as a form field that I can retrieve via $_FILES.
This function in particular:
function (fileName, successFct) {
getFileSystem(function (fileSystem) {
var fd = new FormData();
var xhr = new XMLHttpRequest();
xhr.open('POST', 'upload.php', true);
xhr.onload = function(e) {
if (this.status == 200) {
console.log(this.responseText);
}
};
fileSystem.root.getFile(fileName, {}, function (fileEntry) {
fileEntry.file(function(file) {
fd.append('file' + i, file);
fd.append('name' + i, 'name' + i);
});
}, errorFct);
xhr.send(fd);
}
);
};
Full code can be seen # http://pastebin.com/W0x9q6YH
In upload.php if I do the following
print_r($_FILES);
print_r($_POST);
It just shows two empty arrays.
Struggling with a similar problem: one thing I noticed about your code, you do not set your Content-Type header to multipart/form-data.
I do not have a working sample yet, but I'm pretty sure to use FormData, you need that old multipart/form-data magic.
I'm using this code snippet from gDrive SDK for javascript to download file :
function downloadFile(file, callback) {
if (file.downloadUrl) {
var accessToken = gapi.auth.getToken().access_token;
var xhr = new XMLHttpRequest();
xhr.open('GET', file.downloadUrl);
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
xhr.onload = function() {
callback(xhr.responseText);
};
xhr.onerror = function() {
callback(null);
};
xhr.send();
} else {
callback(null);
}
}
How can i prompt the browser to open the download window when the ajax request is done. How to make the callback function in order to open the dialog for saving the file locally ?
Unfortunately, your approach won't work.
Because of standard browser security constraints, you can't save a file from Javascript.[1]
What you need to do is use the downloadUrl in a new window or src for an iframe to cause the browser to download the file, and prompt the user to save it. You will need to add
&access_token=ya29.YOURACCESSTOKENHERE
to the URL to avoid a 401 error.
Notes
1. Yes I know that HTML5 is starting to support limited filesystem access from Javascript, but (1) it's not widely available, (2) has restrictions on where the file can be saved, and (3) isn't the UX that the OP was asking for.
I have a problems downloading and saving locally the content of a blob from a container through the browser. Uploading a blob to a container worked properly but I can't download it using Firefox or Chrome. The only thing I achieved was retrieving the content in the reponse (Firefox) and I could download it only because of the Chrome cache (that is not valid for me). This is the code I am using:
<script type="text/javascript">
function uploadFile() {
var token = 'AUTH_AAAAAAAA';
var method = 'GET';
var url = 'http://ip/v1/AUTH_account/containerName/blobName';
var xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.setRequestHeader('X-Auth-Token', token);
xhr.setRequestHeader('accept', 'application/octet-stream');
xhr.send();
}
</script>
I cannot just use
<a href='http://ip/v1/AUTH_account/containerName/blobName' onclick='javascript:uploadFile();'>Blob to download</a>
because this link needs the Auth Token and it would respond with a "401 Unauthorized" message.
Thanks for your help.