Upload ảnh lên Imgur bằng JavaScript + Cloudflare Workers

Tổng 2 câu trả lời. Đang xem câu 1 - 2
  • Người viết
    Bình luận
  • #6231
    PhuongCutePhuongCute
    Thành viên

      Trước tiên phải nói rõ: đoạn code này không phải của mình, mà là của bạn
      @Trùm bên diễn đàn Dorew.
      Mình chỉ là người đọc lại, dùng thử thấy chạy ổn nên mang về reShare cho anh em nào cần.

      Bài viết gốc của bạn @Trùm tại đây:


      https://dorew.ovh/forum/488-code-js-upload-anh-su-dung-api-imgur-debug.html

      <h2>1. Tổng quan cách hoạt động</h2>
      Ý tưởng chính của đoạn code này là:

      • Dùng Cloudflare Workers làm một lớp proxy
      • Website của bạn không gọi trực tiếp API Imgur
      • Client chỉ gửi ảnh lên Workers
      • Workers đứng giữa, gắn Client-ID rồi forward request sang Imgur

      Cách này giúp:

      • Tránh lỗi CORS
      • Không lộ API trực tiếp từ frontend
      • Dễ nhúng vào các project JS khác

      Thú thật là mình đọc code lần đầu cũng không hiểu hết từng dòng hoạt động ra sao 😅
      Nhưng vì test thấy upload được ảnh thật nên mình vẫn quyết định dùng code gốc.
      <h2>2. Tạo Cloudflare Worker</h2>
      Vào trang quản lý Cloudflare:

      1. Dashboard Cloudflare
      2. Workers & Pages
      3. Create Application
      4. Start with Hello World

      Sau đó đặt tên cho Worker.
      Ví dụ của mình là:
      rainy.rainylirss.workers.dev
      Lưu lại, rồi dán toàn bộ đoạn code dưới đây vào Worker:

      addEventListener("fetch", event => {
      event.respondWith(handleRequest(event.request));
      });
      
      async function handleRequest(request) {
      const corsHeaders = {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "POST, OPTIONS",
      "Access-Control-Allow-Headers": "Content-Type",
      };
      
      if (request.method === "OPTIONS") {
      return new Response(null, { headers: corsHeaders });
      }
      
      if (request.method !== "POST") {
      return new Response(JSON.stringify({ error: "Method Not Allowed" }), {
      status: 405,
      headers: { "Content-Type": "application/json", ...corsHeaders },
      });
      }
      
      const url = new URL(request.url);
      const clientId = url.searchParams.get("clientId");
      
      if (!clientId) {
      return new Response(JSON.stringify({
      success: false,
      error: "Missing clientId query parameter"
      }), {
      status: 400,
      headers: { "Content-Type": "application/json", ...corsHeaders },
      });
      }
      
      const formData = await request.formData();
      const image = formData.get("image");
      
      if (!image) {
      return new Response(JSON.stringify({
      success: false,
      error: "No image provided"
      }), {
      status: 400,
      headers: { "Content-Type": "application/json", ...corsHeaders },
      });
      }
      
      const imgurForm = new FormData();
      imgurForm.append("image", image);
      
      const userAgent = request.headers.get("User-Agent") || "Mozilla/5.0";
      
      const imgurResponse = await fetch("https://api.imgur.com/3/image", {
      method: "POST",
      body: imgurForm,
      headers: {
      "Authorization": <code>Client-ID ${clientId}

      ,
      “User-Agent”: userAgent,
      },
      });

      const data = await imgurResponse.json();

      return new Response(JSON.stringify(data), {
      status: imgurResponse.status,
      headers: {
      “Content-Type”: “application/json”,
      …corsHeaders
      },
      });
      }

      <h2>3. Tạo file HTML frontend</h2>
      Ở phía website, bạn chỉ cần tạo 1 file HTML bất kỳ
      rồi dán đoạn code HTML + JS dưới đây vào.

      
      <!DOCTYPE html><br><html lang="vi"><br><head><br>  <meta charset="UTF-8" /><br>  <title>Imgur Upload via Proxy</title><br>  <script src="https://cdn.tailwindcss.com"></script><br></head><br><body class="bg-gray-100 min-h-screen flex items-center justify-center p-6"><br><br>  <div class="bg-white shadow-lg rounded-xl w-full max-w-xl p-6 space-y-4"><br>    <h1 class="text-2xl font-bold text-center">📤 Upload ảnh lên Imgur</h1><br><br>    <input<br>      type="file"<br>      id="fileInput"<br>      accept="image/*"<br>      class="block w-full text-sm text-gray-500<br>             file:mr-4 file:py-2 file:px-4<br>             file:rounded-full file:border-0<br>             file:text-sm file:font-semibold<br>             file:bg-blue-50 file:text-blue-700<br>             hover:file:bg-blue-100"<br>    /><br><br>    <input<br>      type="text"<br>      id="clientId"<br>      placeholder="Client ID (fake cũng được 😆)"<br>      class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring"<br>    /><br><br>    <button<br>      id="uploadBtn"<br>      class="w-full bg-blue-600 text-white py-2 rounded-lg hover:bg-blue-700 transition"<br>    ><br>      Upload<br>    </button><br><br>    <div id="result" class="hidden space-y-2"><br>      <h2 class="font-semibold text-lg">📎 Kết quả</h2><br><br>      <div class="space-y-1 text-sm"><br>        
      
      

      <br>

      
      

      <br>

      
      

      <br>

      
      

      <br>

      
      

      <br>

      
      

      <br> </div><br> </div><br> </div><br><br> <script><br> class ImgurUploader {<br> constructor(proxyUrl) {<br> this.proxyUrl = proxyUrl;<br> }<br><br> toBase64(file) {<br> return new Promise((resolve, reject) => {<br> const reader = new FileReader();<br> reader.onload = () => resolve(reader.result.split(",")[1]);<br> reader.onerror = reject;<br> reader.readAsDataURL(file);<br> });<br> }<br><br> async upload(file, clientId) {<br> const base64 = await this.toBase64(file);<br><br> const res = await fetch(<br> ${this.proxyUrl}?clientId=${clientId},<br> {<br> method: "POST",<br> headers: {<br> "Content-Type": "application/json"<br> },<br> body: JSON.stringify({<br> image: base64,<br> type: "base64"<br> })<br> }<br> );<br><br> const json = await res.json();<br><br> if (!json?.data?.link) {<br> throw new Error("Upload thất bại");<br> }<br><br> const link = json.data.link;<br><br> return {<br> view: link,<br> bbcode: [img]${link}[/img],<br> markdown: ![image](${link}),<br> html: <img src="${link}" alt="image">,<br> yaml: image: ${link},<br> xml: <image>${link}</image><br> };<br> }<br> }<br><br> const uploader = new ImgurUploader(<br> "https://rainy.rainylirss.workers.dev/"<br> );<br><br> document.getElementById("uploadBtn").onclick = async () => {<br> const file = document.getElementById("fileInput").files[0];<br> const clientId = document.getElementById("clientId").value.trim();<br> const resultBox = document.getElementById("result");<br><br> if (!file || !clientId) {<br> alert("Chọn ảnh và nhập Client ID nha bạn 😅");<br> return;<br> }<br><br> try {<br> const result = await uploader.upload(file, clientId);<br><br> resultBox.classList.remove("hidden");<br><br> document.getElementById("view").textContent =<br> View Link:\n${result.view};<br><br> document.getElementById("bbcode").textContent =<br> BBCode:\n${result.bbcode};<br><br> document.getElementById("markdown").textContent =<br> Markdown:\n${result.markdown};<br><br> document.getElementById("html").textContent =<br> HTML:\n${result.html};<br><br> document.getElementById("yaml").textContent =<br> YAML:\n${result.yaml};<br><br> document.getElementById("xml").textContent =<br> XML:\n${result.xml};<br><br> } catch (e) {<br> alert(e.message);<br> }<br> };<br> </script><br></body><br></html><br>

      Đoạn code này sử dụng:

      • JavaScript thuần
      • Class JS để dễ tái sử dụng
      • Tailwind CSS qua CDN

      Lưu ý:
      Trong phần JS, bạn cần:

      • Thay URL Worker của bạn (vì URL của mình có thể bị xoá)
      • Nhập Client ID Imgur thật thì mới upload được

      (Đoạn HTML code dài nên mình giữ nguyên như phần trên bạn đã có.)
      <h2>4. Bảng so sánh điểm mạnh & điểm yếu</h2>
      <table>
      <thead>
      <tr>
      <th>Điểm mạnh</th>
      <th>Điểm yếu</th>
      </tr>
      </thead>
      <tbody>
      <tr>
      <td>✔ Không bị CORS
      ✔ Không cần backend riêng
      ✔ Dễ deploy, miễn phí với Cloudflare
      ✔ JS thuần, dễ nhét vào project khác</td>
      <td>✖ Phụ thuộc Imgur API
      ✖ Cần Client-ID hợp lệ
      ✖ Không có xác thực người dùng
      ✖ Worker công khai dễ bị abuse nếu lộ link</td>
      </tr>
      </tbody>
      </table>
      <h2>5. Kết luận</h2>
      Nhìn chung, đây là một cách làm đơn giản – gọn – dễ dùng
      cho những ai chỉ cần upload ảnh nhanh để lấy link nhét vào code khác.

      Không phù hợp cho hệ thống lớn hay cần bảo mật cao,
      nhưng dùng cho tool cá nhân, blog, forum, demo thì quá ổn.

      Cuối cùng, mở web lên, upload ảnh và tận hưởng thành quả thôi 😄

      Code dùng JS thuần, mục đích chính là lấy link ảnh để dùng tiếp trong code khác cũng như về tách code ra để nhét vào code khác là chính.

      • Chủ đề này đã được điều chỉnh 4 tháng trước bởi PhuongCutePhuongCute.
      #6232
      PhuongCutePhuongCute
      Thành viên

        ơ sao lúc viết bài trong form nó vẫn hiện html mà lúc viết ra lại không cho xài h2 với table

      Tổng 2 câu trả lời. Đang xem câu 1 - 2
      • Bạn cần đăng nhập để phản hồi chủ đề này.