Maison >développement back-end >Golang >le type de contenu de l'en-tête du serveur Go http est défini sur multipart/form-data mais côté client, il obtient Content-Type : text/plain

le type de contenu de l'en-tête du serveur Go http est défini sur multipart/form-data mais côté client, il obtient Content-Type : text/plain

WBOY
WBOYavant
2024-02-12 22:57:081201parcourir

go http 服务器标头内容类型设置为 multipart/form-data 但在客户端获取 Content-Type: text/plain

En développement web, il est souvent nécessaire d'utiliser des requêtes HTTP pour transmettre des données. Dans certains cas, nous devrons peut-être définir le type de contenu demandé sur multipart/form-data et obtenir des données avec un type de contenu text/plain côté client. Ces paramètres peuvent être configurés dans les en-têtes du serveur HTTP. En PHP, nous pouvons atteindre cet objectif grâce aux fonctions et méthodes correspondantes. Dans cet article, l'éditeur PHP Xigua vous présentera comment définir le type de contenu d'en-tête du serveur HTTP sur multipart/form-data en PHP et obtenir les données avec Content-Type de text/plain sur le client.

Contenu de la question

Le serveur Go définit l'en-tête Content-type sur multipart/form-data

router.HandleFunc("/certificates", serveFilesHandler).Methods("GET")

func serveFilesHandler(w http.ResponseWriter, r *http.Request) {

    currentDir, err := os.Getwd()
    if err != nil {
        log.Fatal("Can not find the current directory: ", err)
    }
    pathToCertifs := "../certificates"

    // Create a multipart writer for the response
    multipartWriter := multipart.NewWriter(w)

    files := []string{"client.key", "server.key", "rootCA.key"}

    for _, filename := range files {
        filePath := filepath.Join(currentDir, pathToCertifs, filename)

        fmt.Println("see the filePath: ", filePath)

        // Open the file
        file, err := os.Open(filePath)
        if err != nil {}
        defer file.Close()

        // Create a new form file part
        part, err := multipartWriter.CreateFormFile("files", filename)
        if err != nil {}

        // Copy the file content to the part
        _, err = io.Copy(part, file)
        if err != nil {}
    }

    // Set the content type for the response
    w.Header().Set("Content-Type", multipartWriter.FormDataContentType())
    fmt.Println("Content-Type set to:", w.Header().Get("Content-Type"))
    // printout Content-Type set to: multipart/form-data; boundary=7b326

    // Close the multipart writer
    multipartWriter.Close()
}

Mais côté client, je reçois

Expected multipart response, but received: text/plain; charset=utf-8

Mais la charge utile est dans le corps

body, err := ioutil.ReadAll(resp.Body)
    if err != nil {}
Content-Type: text/plain; charset=utf-8
Response Body:
--aee406774ba6a054d52e39a3cdb72f42d32bd30828adbfb1982d278cab56
Content-Disposition: form-data; name="files"; filename="client.key"
Content-Type: application/octet-stream

-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDNg4ZaTLC/GdLK
xzFDIyPlYyKs/hUXpPkZAQk+3gnvmBaDuMNq2jd2nQoQohmk1zIuD8oj9se5L+3P

Mais je ne peux pas l'obtenir par partie car le type de contenu n'est pas multipart/form-data, donc cela ne fonctionne pas

multipartReader := multipart.NewReader(resp.Body, boundaryFromContentType(contentType))

    // Read each part
    for {
        part, err := multipartReader.NextPart()
        if err != nil {
            break
        }
        defer part.Close()
......

Qu'est-ce qui me manque, merci ?

ps : Cette question nécessitait plus de détails, je la trouvais assez claire, alors j'ai ajouté cette ligne, cela pourrait fonctionner plus tard.

Solution

Les en-têtes de réponse HTTP doivent être définis avant que quoi que ce soit ne soit écrit dans le corps de la réponse. Une fois les en-têtes soumis (lorsque vous écrivez dans le corps de la réponse), vous ne pouvez pas définir ou modifier les en-têtes.

Vous créez l'écrivain en plusieurs parties ainsi que toutes les parties et le contenu, puis définissez les en-têtes de réponse, puis fermez simplement l'écrivain en plusieurs parties. La fermeture consiste simplement à compléter le message en plusieurs parties et à écrire la limite finale, mais une grande partie de son contenu a peut-être déjà été écrite et validée.

Déplacez l'en-tête des paramètres avant d'ajouter/d'écrire quoi que ce soit dans l'écrivain en plusieurs parties :

// Create a multipart writer for the response
multipartWriter := multipart.NewWriter(w)

w.Header().Set("Content-Type", multipartWriter.FormDataContentType())

// Now proceed to add files...

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer