Last active
January 11, 2021 22:24
-
-
Save shaneosullivan/12d41c10f6ebf2aa07359d38fa0899a2 to your computer and use it in GitHub Desktop.
Example of signing a Cloudinary video upload request and uploading it from a browser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Run in the browser | |
// This function takes "someId" as a parameter, as an example that you | |
// may want to link the video upload to some object in your database. | |
// This is of course totally optional. | |
function uploadVideo( | |
someId: number, | |
file: File, | |
listeners: { | |
onProgress: (perc: number) => void; | |
onComplete: (url: string) => void; | |
onError: (str: string) => void; | |
} | |
): () => void { | |
let cancelableXhr = null; | |
fetch("/api/signCloudinaryUpload", { | |
method: "POST", | |
cache: "no-cache", | |
credentials: "include", | |
headers: { | |
"Content-Type": "application/json", | |
}, | |
body: JSON.stringify({ | |
someId | |
}), | |
}) | |
.then((res) => { | |
if (!res.ok) { | |
listeners.onError("Permission to upload denied"); | |
} else { | |
return res.json(); | |
} | |
}) | |
.then((signatureInfo) => { | |
cancelableXhr = runUpload( | |
signatureInfo.cloud_name, | |
signatureInfo.api_key, | |
signatureInfo.signature, | |
signatureInfo.public_id, | |
signatureInfo.timestamp | |
); | |
}); | |
function runUpload(cloudName, apiKey, signature, publicId, timestamp) { | |
const url = `https://api.cloudinary.com/v1_1/${cloudName}/upload`; | |
const xhr = new XMLHttpRequest(); | |
const fd = new FormData(); | |
xhr.open("POST", url, true); | |
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); | |
listeners.onProgress(0); | |
// Update progress (can be used to show progress indicator) | |
xhr.upload.addEventListener("progress", function(e) { | |
const progress = Math.round((e.loaded * 100.0) / e.total); | |
listeners.onProgress(progress); | |
console.log( | |
`fileuploadprogress data.loaded: ${e.loaded}, data.total: ${e.total}` | |
); | |
}); | |
xhr.onreadystatechange = function(e) { | |
if (xhr.readyState == 4 && xhr.status == 200) { | |
// File uploaded successfully | |
const response = JSON.parse(xhr.responseText); | |
console.log("response", response); | |
// Create a thumbnail of the uploaded image, with 150px width | |
listeners.onComplete(response.secure_url); | |
} | |
}; | |
fd.append("api_key", apiKey); | |
fd.append("public_id", publicId); | |
fd.append("timestamp", timestamp); | |
fd.append("signature", signature); | |
fd.append("file", file); | |
xhr.send(fd); | |
} | |
return () => { | |
cancelableXhr && cancelableXhr.abort(); | |
}; | |
} | |
// Run on the server | |
import { v2 as cloudinary } from "cloudinary"; | |
cloudinary.config({ | |
cloud_name: "", // Your cloud name | |
api_key: "", // your api key | |
api_secret: "", // your api secret | |
}); | |
function signCloudinaryRequest(publicId: string) { | |
const timestamp = Math.round(new Date().getTime() / 1000); | |
const apiSecret = (cloudinary.config("api_secret") as any) as string; | |
const signature = cloudinary.utils.api_sign_request( | |
{ | |
timestamp, | |
public_id: publicId, | |
}, | |
apiSecret | |
); | |
return { | |
api_key: (cloudinary.config("api_key") as any) as string, | |
signature, | |
cloud_name: (cloudinary.config("cloud_name") as any) as string, | |
timestamp, | |
}; | |
} | |
function apiHandler(request, response) { | |
// This assumes that you have a bodyParser set up | |
const someId = request.body.someId; | |
const publicId = `${someId}/video`; // use whatever path you like | |
const signatureInfo = signCloudinaryRequest(publicId); | |
response.status(200); | |
response.json({ | |
api_key: signatureInfo.api_key, | |
cloud_name: signatureInfo.cloud_name, | |
public_id: publicId, | |
signature: signatureInfo.signature, | |
timestamp: signatureInfo.timestamp, | |
}); | |
response.end(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment