This article shows how to upload files to Google Cloud Storage using Javascript on only the browser (without Node.js).
Implementation
This source code was made based on GCP(Google Cloud Platform) Official reference. This article uses JSON API GCP provides and OAuth2.0.
Auth (OAuth2.0)
The goal in this section is to get an access token to access Cloud Storage. We get it through Google OAuth2.0. "OAuth 2.0 for Client-side Web Applications" shows us the necessary source code for authorization. This is a reference to make the following source code.
Get Necessary Information
You need to get the necessary information to use Cloud Storage through JSON API. These are the following three items.
- Client ID
- Redirect URL
- Scope
Please refer to "How to get Google Client ID and Client Secret?" if you do not have any idea to get them. Additionally, please make the "OAuth consent screen." Please select the appropriate scope according to "
Cloud Storage authentication".
Get Access Token (Source Code and Result)
This section shows the source code that gets access token only. It provides the function to get an access token through the OAuth consent screen when the user clicks the "Get Access Token" button.
Source Code
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript" src="/index.js" defer></script>
</head>
<body>
<button onclick="oauthSignIn()">Get Access Token</button>
<form id="formElem">
<input type="file" id="file-upload" name="file-upload" />
<input type="submit" id="submit-button" disabled />
</form>
</body>
</html>
index.js
/**
* Extract the access token from the URL
*/
for (value of location.hash.split("&")) {
if (value.indexOf("access_token=") === 0) {
const access_token = value.split("=")[1];
const ele = document.createElement("p");
ele.textContent = "Your access token is '" + access_token + "'.";
document.body.appendChild(ele);
}
}
/**
* The following source code is from the page.
* https://developers.google.com/identity/protocols/oauth2/javascript-implicit-flow#oauth-2.0-endpoints
*/
/*
* Create a form to request an access token from Google's OAuth 2.0 server.
*/
function oauthSignIn() {
// Google's OAuth 2.0 endpoint for requesting an access token
var oauth2Endpoint = "https://accounts.google.com/o/oauth2/v2/auth";
// Create <form> element to submit parameters to OAuth 2.0 endpoint.
var form = document.createElement("form");
form.setAttribute("method", "GET"); // Send as a GET request.
form.setAttribute("action", oauth2Endpoint);
// Parameters to pass to OAuth 2.0 endpoint.
var params = {
client_id: [Client ID you set up before section],
redirect_uri: [Refirect URL you set up before section, for example, "http://localhost:3000"],
response_type: "token",
scope: [Scope you set up before section, for example, "https://www.googleapis.com/auth/devstorage.read_write"],
include_granted_scopes: "true",
state: "pass-through value",
};
// Add form parameters as hidden input values.
for (var p in params) {
var input = document.createElement("input");
input.setAttribute("type", "hidden");
input.setAttribute("name", p);
input.setAttribute("value", params[p]);
form.appendChild(input);
}
// Add form to page and submit it to open the OAuth 2.0 endpoint.
document.body.appendChild(form);
form.submit();
}
Result
Upload Files to Cloud Storage (Source Code and Result)
This section shows how to upload files to Cloud Storage using the access token you get in the previous section. You need to make a new bucket on Cloud Console. If you don't know how to make it, please refer to "Create storage buckets".
Source Code
The HTML file is the same as before. Please fix the Javascript source code as the following.
index.js
const bucketName = [Bucket name you made];
const clientID = [Client ID you set up];
const redirectURL = [Redirect URL];
const scope = [Scope];
let accessToken = null;
/**
* Extract the access token from the redirect URL
*/
for (value of location.hash.split("&")) {
if (value.indexOf("access_token=") === 0) {
const access_token = value.split("=")[1];
const ele = document.createElement("p");
ele.textContent = "Your access token is '" + access_token + "'.";
accessToken = access_token;
document.body.appendChild(ele);
document.getElementById("submit-button").disabled = false;
}
}
/**
* Upload file
*/
formElem.onsubmit = async (e) => {
e.preventDefault();
const file = document.getElementById("file-upload");
const filename = file.value.split("\\").slice(-1)[0];
console.log("File Name: " + JSON.stringify(filename));
const extension = filename.split(".").slice(-1)[0].toLocaleLowerCase();
let contentType = null;
// Detect Content Type
if (extension === "png") {
contentType = "image/png";
} else if (extension === "jpg" || extension === "jpeg") {
contentType = "image/jpeg";
} else if (extension === "svg") {
contentType = "image/svg+xml";
} else if (extension === "mpeg") {
contentType = "video/mpeg";
} else if (extension === "webm") {
contentType = "video/webm";
} else {
alert("This file is invalid.");
}
// Load file and upload it
if (contentType) {
const reader = new FileReader();
reader.addEventListener("load", async (event) => {
const bytes = event.target.result;
let response = await fetch(
`https://storage.googleapis.com/upload/storage/v1/b/${bucketName}/o?uploadType=media&name=${filename}`,
{
method: "POST",
headers: {
"Content-Type": contentType,
Authorization: `Bearer ${accessToken}`,
},
body: bytes,
}
);
let result = await response.json();
if (result.mediaLink) {
alert(
`Success to upload ${filename}. You can access it to ${result.mediaLink}`
);
} else {
alert(`Failed to upload ${filename}`);
}
});
reader.readAsArrayBuffer(file.files[0]);
}
};
/**
* The following Source code originated from https://developers.google.com/identity/protocols/oauth2/javascript-implicit-flow#oauth-2.0-endpoints
*/
/*
* Create a form to request an access token from Google's OAuth 2.0 server.
*/
function oauthSignIn() {
// Google's OAuth 2.0 endpoint for requesting an access token
var oauth2Endpoint = "https://accounts.google.com/o/oauth2/v2/auth";
// Create <form> element to submit parameters to OAuth 2.0 endpoint.
var form = document.createElement("form");
form.setAttribute("method", "GET"); // Send as a GET request.
form.setAttribute("action", oauth2Endpoint);
// Parameters to pass to OAuth 2.0 endpoint.
var params = {
client_id: clientID,
redirect_uri: redirectURL,
response_type: "token",
scope: scope,
include_granted_scopes: "true",
state: "pass-through value",
};
// Add form parameters as hidden input values.
for (var p in params) {
var input = document.createElement("input");
input.setAttribute("type", "hidden");
input.setAttribute("name", p);
input.setAttribute("value", params[p]);
form.appendChild(input);
}
// Add form to page and submit it to open the OAuth 2.0 endpoint.
document.body.appendChild(form);
form.submit();
}
Result
I list references in the following.
- MIME Types
- upload file to Cloud Storage using
curl
-
fetch
usage
-
<input type="file">
usage
The original article is the following. This article was translated from Japanese to English.
Top comments (1)
What is "Redirect URL"? I know that is a "Authorized redirect URIs" of client ID but is the same page of this code?