Skip to content

Instantly share code, notes, and snippets.

@tatsuyasusukida
Last active August 3, 2022 00:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tatsuyasusukida/1e782b0042f5fe5b12c9a5639b61635a to your computer and use it in GitHub Desktop.
Save tatsuyasusukida/1e782b0042f5fe5b12c9a5639b61635a to your computer and use it in GitHub Desktop.
๐Ÿ—ƒ๏ธ How to upload files from browser to Google Cloud Storage
PORT="3000"
BUCKET="gcp-file-upload-00000000"
/node_modules/
/.env
/package-lock.json
# Do not ignore package-lock.json other than gist
main()
function main () {
const el = {
file: document.querySelector('#file'),
submit: document.querySelector('#submit'),
list: document.querySelector('#list'),
}
el.submit.addEventListener('click', async (event) => {
event.preventDefault()
const [file] = el.file.files
if (file) {
const url = '/api/v1/upload?' + new URLSearchParams({
filename: file.name,
}).toString()
const response = await fetch(url, {
method: 'POST',
body: file,
})
if (response.status === 201) {
const url = response.headers.get('Location')
el.list.innerHTML += `
<li>
<a href="${url}" target="_blank">${url}</a>
</li>
`
}
}
})
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>How to upload files from browser to Google Cloud Storage</title>
</head>
<body>
<h1>How to upload files from browser to Google Cloud Storage</h1>
<form>
<label for="file">File</label>
<input type="file" name="file" id="file">
<button type="submit" id="submit">Upload</button>
</form>
<ul id="list"></ul>
<script src="client.js"></script>
</body>
</html>
{
"name": "gcp-file-upload",
"version": "1.0.0",
"description": "",
"main": "server.mjs",
"scripts": {
"bucket:mb": "source .env && gsutil mb -l asia-northeast1 gs://$BUCKET",
"bucket:ls": "source .env && gsutil ls gs://$BUCKET",
"bucket:rb": "source .env && gsutil rb gs://$BUCKET",
"dev": "nodemon -r dotenv/config server.mjs",
"gist": "source .env && gist -u $GIST_ID -od '๐Ÿ—ƒ๏ธ How to upload files from browser to Google Cloud Storage' .env.example .gitignore client.js index.html package.json server.mjs test.txt upload.mjs"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"@google-cloud/storage": "^6.3.0",
"dotenv": "^16.0.1",
"express": "^4.18.1"
}
}
import path from 'path'
import express from 'express'
import {upload} from './upload.mjs'
main()
async function main () {
try {
const router = express()
router.get('/', sendFile('index.html'))
router.get('/client.js', sendFile('client.js'))
router.post('/api/v1/upload', upload)
router.use((_, res) => {
res.status(404).end()
})
router.use((err, _, res, __) => {
res.status(err.status || 500).end()
console.error(err)
})
const port = parseInt(process.env.PORT, 10)
router.listen(port, () => {
console.info(`Listening on ${port}`)
})
} catch (err) {
console.error(err)
}
}
function sendFile (filename) {
const {pathname} = new URL(import.meta.url)
const dirname = path.dirname(pathname)
const file = path.join(dirname, filename)
return (_, res) => {
res.sendFile(file)
}
}
import path from 'path'
import {Storage} from '@google-cloud/storage'
export async function upload (req, res, next) {
try {
const buffer = await new Promise((resolve, reject) => {
const chunks = []
req.on('data', (chunk) => chunks.push(chunk))
req.on('end', () => resolve(Buffer.concat(chunks)))
req.on('error', (err) => reject(err))
})
const storage = new Storage()
const bucket = storage.bucket(process.env.BUCKET)
const basename = Date.now()
const extname = path.extname(req.query.filename)
const file = bucket.file(basename + extname)
await file.save(buffer)
await file.makePublic()
res.status(201).set('Location', file.publicUrl()).end()
} catch (err) {
next(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment