Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>It is possible to use the Google APIs Javascript client library with Drive but you have to be aware that there are some pain points.</p> <p>There are 2 main issues currently, both of which have workarrounds:</p> <h2>Authorization</h2> <p>First if you have a look closely at how Google Drive auth works you will realize that, after a user has installed your Drive application and tries to open a file or create a new file with your application, Drive initiates the OAuth 2.0 authorization flow automatically and the auth parameters are set to <strong>response_type=code</strong> and <strong>access_type=offline</strong>. This basically means that right now Drive apps are forced to use the OAuth 2 server-side flow which is not going to be of any use to the Javascript client library (which only uses the client-side flow).</p> <p>The issue is that: Drive initiates a server-side OAuth 2.0 flow, then the Javascript client library initiates a client-side OAuth 2.0 flow.</p> <p>This can still work, all you have to do it is use server-side code to process the authorization code returned after the Drive server-side flow (you need to exchange it for an access token and a refresh token). That way, only on the first flow will the user be prompted for authorization. After the first time you exchange the authorization code, the auth page will be bypassed automatically.</p> <p>Server side samples to do this is available <a href="https://developers.google.com/drive/credentials" rel="noreferrer">in our documentation</a>.</p> <p>If you don't process/exchange the auth code on the server-side flow, the user will be prompted for auth every single time he tries to use your app from Drive.</p> <h2>Handling file content</h2> <p>The second issue is that uploading and accessing the actual Drive file content is not made easy by our Javascript client library. You can still do it but you will have to use custom Javascript code.</p> <p><strong>Reading the file content</strong></p> <p>When a file metadata/a file object is retrieved, it contains a <code>downloadUrl</code> attribute which points to the actual file content. It is now possible to download the file using a CORS request and the simplest way to auth is to use the OAuth 2 access token in a URL param. So just append <code>&amp;access_token=...</code> to the <code>downloadUrl</code> and fetch the file using XHR or by forwarding the user to the URL.</p> <p><strong>Uploading file content</strong></p> <p>UPDATE UPDATE: The upload endpoints <strong>do</strong> now support CORS.</p> <p>~~UPDATE: The upload endpoints, unlike the rest of the Drive API do not support CORS so you'll have to use the trick below for now:~~</p> <p>Uploading a file is tricky because it's not built-in the Javascript client lib and you can't entirely do it with HTTP as described in <a href="https://stackoverflow.com/questions/10317638/inserting-file-to-google-drive-through-api/10323612#10323612">this response</a> because we don't allow cross-domain requests on these API endpoints. So you do have to take advantage of the iframe proxy used by our Javascript client library and use it to send a constructed multipart request to the Drive SDK. Thanks to <a href="https://stackoverflow.com/users/1106381/alain">@Alain</a>, we have an sample of how to do that below:</p> <pre><code>/** * Insert new file. * * @param {File} fileData File object to read data from. * @param {Function} callback Callback function to call when the request is complete. */ function insertFileData(fileData, callback) { const boundary = '-------314159265358979323846'; const delimiter = "\r\n--" + boundary + "\r\n"; const close_delim = "\r\n--" + boundary + "--"; var reader = new FileReader(); reader.readAsBinaryString(fileData); reader.onload = function(e) { var contentType = fileData.type || 'application/octet-stream'; var metadata = { 'title': fileData.fileName, 'mimeType': contentType }; var base64Data = btoa(reader.result); var multipartRequestBody = delimiter + 'Content-Type: application/json\r\n\r\n' + JSON.stringify(metadata) + delimiter + 'Content-Type: ' + contentType + '\r\n' + 'Content-Transfer-Encoding: base64\r\n' + '\r\n' + base64Data + close_delim; var request = gapi.client.request({ 'path': '/upload/drive/v2/files', 'method': 'POST', 'params': {'uploadType': 'multipart'}, 'headers': { 'Content-Type': 'multipart/mixed; boundary="' + boundary + '"' }, 'body': multipartRequestBody}); if (!callback) { callback = function(file) { console.log(file) }; } request.execute(callback); } } </code></pre> <hr> <p>To improve all this, in the future we might:</p> <ul> <li>Let developers choose which OAuth 2.0 flow they want to use (server-side or client-side) or let the developer handle the OAuth flow entirely.</li> <li>Allow CORS on the <code>/upload/...</code> endpoints</li> <li>Allow CORS on the <code>exportLinks</code> for native gDocs</li> <li>We should make it easier to upload files using our Javascript client library.</li> </ul> <p>No promises at this point though :)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload