DEV Community

Weerasak Chongnguluam
Weerasak Chongnguluam

Posted on

6 2

ใช้ Content-Disposition header ทำให้ browser download ไฟล์แทนที่จะเปิดใน browser

วันก่อนต้องเขียน API endpoint นึงแต่ไม่ใช่ ตอบกลับเป็น JSON แต่จะตอบเป็น content ของ PDF แทน ซึ่งเราอยากให้เมื่อกดลิ้งมาที่ endpoint นี้จากทาง browser แล้วให้ browser นั้นโหลดไฟล์ แทนที่จะเปิดไฟล์ผ่าน browser

วิธีที่ช่วยได้คือกำหนดค่าให้กับ header ที่ชื่อ Content-Disposition

เรามาดูตัวอย่างธรรมดากันก่อนแบบไม่ใช้ Content-Disposition ว่าพฤติกรรมของ browser นั้นเป็นยังไง ตัวอย่างเป็นโค้ด Go

ถ้าเรามีโค้ดแบบนี้

package main

import (
    "log"
    "net/http"
    "os"
)

func main() {
    http.HandleFunc("/cat.jpg", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "image/jpeg")
        b, err := os.ReadFile("image.jpg")
        if err != nil {
            log.Fatal(err)
        }
        w.Write(b)
    })

    http.HandleFunc("/index.html", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "text/html")
        b, err := os.ReadFile("index.html")
        if err != nil {
            log.Fatal(err)
        }
        w.Write(b)
    })

    http.ListenAndServe(":8000", nil)
}
Enter fullscreen mode Exit fullscreen mode

และส่วนของ index.html เป็นแบบนี้

<!DOCTYPE html>
<html lang="en">
<head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Load</title>
</head>
<body>
        <a href="/cat.jpg">Download Picture</a>
</body>
</html>

Enter fullscreen mode Exit fullscreen mode

เมื่อรันโค้ดแล้วเข้าไปที่ localhost:8000/index.html จะเจอลิ้ง download แบบนี้

Alt Text

และเมื่อเรากดลิ้งจะเห็นว่า browser นั้นเปิดใน browser เลยแบบนี้

Alt Text

ทีนี้ถ้าเราต้องการให้ browser โหลดไฟล์แทนเราสามารถกำหนด header Content-Disposition ไปแบบนี้

package main

import (
    "log"
    "net/http"
    "os"
)

func main() {
    http.HandleFunc("/cat.jpg", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "image/jpeg")
        w.Header().Set("Content-Disposition", `attachment; filename="cat.png"`)
        b, err := os.ReadFile("image.jpg")
        if err != nil {
            log.Fatal(err)
        }
        w.Write(b)
    })

    http.HandleFunc("/index.html", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "text/html")
        b, err := os.ReadFile("index.html")
        if err != nil {
            log.Fatal(err)
        }
        w.Write(b)
    })

    http.ListenAndServe(":8000", nil)
}

Enter fullscreen mode Exit fullscreen mode

ส่วนค่าของ header คือกำหนดเป็น

`attachment; filename="cat.png"`
Enter fullscreen mode Exit fullscreen mode

ตรง filename คือกำหนดชื่อไฟล์ที่จะให้ browser ใช้เซฟตอน download นั่นเอง

Alt Text

ขอฝาก Buy Me a Coffee

สำหรับท่านใดที่อ่านแล้วชอบโพสต์ต่างๆของผมที่นี่ ต้องการสนับสนุนค่ากาแฟเล็กๆน้อยๆ สามารถสนับสนุนผมได้ผ่านทาง Buy Me a Coffee คลิ๊กที่รูปด้านล่างนี้ได้เลยครับ

Buy Me A Coffee

ส่วนท่านใดไม่สะดวกใช้บัตรเครดิต หรือ Paypal สามารถสนับสนุนผมได้ผ่านทาง PromptPay โดยดู QR Code ได้จากโพสต์ที่พินเอาไว้ได้ที่ Page DevDose ครับ https://web.facebook.com/devdoseth

ขอบคุณครับ 🙏

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay