Analyse HTTP des données de type formulaire (multipart/form-data)

Restez organisé à l'aide des collections Enregistrez et classez les contenus selon vos préférences.

Découvrez une fonction Cloud qui analyse les requêtes HTTP de formulaire.

Exemple de code


using Google.Cloud.Functions.Framework;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading.Tasks;

namespace HttpFormData
    public class Function : IHttpFunction
        private readonly ILogger _logger;

        public Function(ILogger<Function> logger) =>
            _logger = logger;

        public async Task HandleAsync(HttpContext context)
            HttpResponse response = context.Response;
            HttpRequest request = context.Request;

            if (request.Method != "POST")
                response.StatusCode = (int) HttpStatusCode.MethodNotAllowed;

            // This code will process each file uploaded.
            string tempDirectory = Path.GetTempPath();
            foreach (IFormFile file in request.Form.Files)
                if (string.IsNullOrEmpty(file.FileName))
                _logger.LogInformation("Processed file: {file}", file.FileName);

                // Note: GCF's temp directory is an in-memory file system
                // Thus, any files in it must fit in the instance's memory.
                string outputPath = Path.Combine(tempDirectory, file.FileName);

                // Note: files saved to a GCF instance itself may not persist across executions.
                // Persistent files should be stored elsewhere, e.g. a Cloud Storage bucket.
                using (FileStream output = File.Create(outputPath))
                    await file.CopyToAsync(output);

                // TODO(developer): process saved files here

            // This code will process other form fields.
            foreach (KeyValuePair<string, StringValues> parameter in request.Form)
                // TODO(developer): process field values here
                _logger.LogInformation("Processed field '{key}' (value: '{value}')",
                    parameter.Key, (string) parameter.Value);


// Package http provides a set of HTTP Cloud Functions samples.
package http

import (

// UploadFile processes a 'multipart/form-data' upload request.
func UploadFile(w http.ResponseWriter, r *http.Request) {
	const maxMemory = 2 * 1024 * 1024 // 2 megabytes.

	// ParseMultipartForm parses a request body as multipart/form-data.
	// The whole request body is parsed and up to a total of maxMemory bytes of
	// its file parts are stored in memory, with the remainder stored on
	// disk in temporary files.

	// Note that any files saved during a particular invocation may not
	// persist after the current invocation completes; persistent files
	// should be stored elsewhere, such as in a Cloud Storage bucket.
	if err := r.ParseMultipartForm(maxMemory); err != nil {
		http.Error(w, "Unable to parse form", http.StatusBadRequest)
		log.Printf("Error parsing form: %v", err)

	// Be sure to remove all temporary files after your function is finished.
	defer func() {
		if err := r.MultipartForm.RemoveAll(); err != nil {
			http.Error(w, "Error cleaning up form files", http.StatusInternalServerError)
			log.Printf("Error cleaning up form files: %v", err)

	// r.MultipartForm.File contains *multipart.FileHeader values for every
	// file in the form. You can access the file contents using
	// *multipart.FileHeader's Open method.
	for _, headers := range r.MultipartForm.File {
		for _, h := range headers {
			fmt.Fprintf(w, "File uploaded: %q (%v bytes)", h.Filename, h.Size)
			// Use h.Open() to read the contents of the file.



import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.logging.Logger;

public class HttpFormData implements HttpFunction {
  private static final Logger logger = Logger.getLogger(HttpFormData.class.getName());

  public void service(HttpRequest request, HttpResponse response)
      throws IOException {

    if (!"POST".equals(request.getMethod())) {

    // This code will process each file uploaded.
    String tempDirectory = System.getProperty("");
    for (HttpRequest.HttpPart httpPart : request.getParts().values()) {
      String filename = httpPart.getFileName().orElse(null);
      if (filename == null) {
      }"Processed file: " + filename);

      // Note: GCF's temp directory is an in-memory file system
      // Thus, any files in it must fit in the instance's memory.
      Path filePath = Paths.get(tempDirectory, filename).toAbsolutePath();

      // Note: files saved to a GCF instance itself may not persist across executions.
      // Persistent files should be stored elsewhere, e.g. a Cloud Storage bucket.
      Files.copy(httpPart.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);

      // TODO(developer): process saved files here

    // This code will process other form fields.
        (fieldName, fieldValues) -> {
          String firstFieldValue = fieldValues.get(0);

          // TODO(developer): process field values here

              "Processed field: %s (value: %s)", fieldName, firstFieldValue));


 * Parses a 'multipart/form-data' upload request
 * @param {Object} req Cloud Function request context.
 * @param {Object} res Cloud Function response context.
const path = require('path');
const os = require('os');
const fs = require('fs');

const functions = require('@google-cloud/functions-framework');

// Node.js doesn't have a built-in multipart/form-data parsing library.
// Instead, we can use the 'busboy' library from NPM to parse these requests.
const Busboy = require('busboy');

functions.http('uploadFile', (req, res) => {
  if (req.method !== 'POST') {
    // Return a "method not allowed" error
    return res.status(405).end();
  const busboy = Busboy({headers: req.headers});
  const tmpdir = os.tmpdir();

  // This object will accumulate all the fields, keyed by their name
  const fields = {};

  // This object will accumulate all the uploaded files, keyed by their name.
  const uploads = {};

  // This code will process each non-file field in the form.
  busboy.on('field', (fieldname, val) => {
     *  TODO(developer): Process submitted field values here
    console.log(`Processed field ${fieldname}: ${val}.`);
    fields[fieldname] = val;

  const fileWrites = [];

  // This code will process each file uploaded.
  busboy.on('file', (fieldname, file, {filename}) => {
    // Note: os.tmpdir() points to an in-memory file system on GCF
    // Thus, any files in it must fit in the instance's memory.
    console.log(`Processed file ${filename}`);
    const filepath = path.join(tmpdir, filename);
    uploads[fieldname] = filepath;

    const writeStream = fs.createWriteStream(filepath);

    // File was processed by Busboy; wait for it to be written.
    // Note: GCF may not persist saved files across invocations.
    // Persistent files must be kept in other locations
    // (such as Cloud Storage buckets).
    const promise = new Promise((resolve, reject) => {
      file.on('end', () => {
      writeStream.on('close', resolve);
      writeStream.on('error', reject);

  // Triggered once all uploaded files are processed by Busboy.
  // We still need to wait for the disk writes (saves) to complete.
  busboy.on('finish', async () => {
    await Promise.all(fileWrites);

     * TODO(developer): Process saved files here
    for (const file in uploads) {



use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Psr7\Response;

function uploadFile(ServerRequestInterface $request): ResponseInterface
    if ($request->getMethod() != 'POST') {
        return new Response(405, [], 'Method Not Allowed: expected POST, found ' . $request->getMethod());

    $contentType = $request->getHeader('Content-Type')[0];
    if (strpos($contentType, 'multipart/form-data') !== 0) {
        return new Response(400, [], 'Bad Request: content of type "multipart/form-data" not provided, found ' . $contentType);

    $fileList = [];
    /** @var $file Psr\Http\Message\UploadedFileInterface */
    foreach ($request->getUploadedFiles() as $name => $file) {
        // Use caution when trusting the client-provided filename:
        $fileList[] = $file->getClientFilename();

        infoLog('Processing ' . $file->getClientFilename());
        $filename = tempnam(sys_get_temp_dir(), $name . '.') . '-' . $file->getClientFilename();

        // Use $file->getStream() to process the file contents in ways other than a direct "file save".
        infoLog('Saving to ' . $filename);

    if (empty($fileList)) {
        $msg = 'Bad Request: no files sent for upload';
        return new Response(400, [], $msg);

    return new Response(201, [], 'Saved ' . join(', ', $fileList));

function errorLog($msg): void
    $stream = fopen('php://stderr', 'wb');
    $entry = json_encode(['msg' => $msg, 'severity' => 'error'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    fwrite($stream, $entry . PHP_EOL);

function infoLog($msg): void
    $stream = fopen('php://stderr', 'wb');
    $entry = json_encode(['message' => $msg, 'severity' => 'info'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    fwrite($stream, $entry . PHP_EOL);


import os
import tempfile
import functions_framework

from werkzeug.utils import secure_filename

# Helper function that computes the filepath to save files to
def get_file_path(filename):
    # Note: tempfile.gettempdir() points to an in-memory file system
    # on GCF. Thus, any files in it must fit in the instance's memory.
    file_name = secure_filename(filename)
    return os.path.join(tempfile.gettempdir(), file_name)

def parse_multipart(request):
    """ Parses a 'multipart/form-data' upload request
        request (flask.Request): The request object.
        The response text, or any set of values that can be turned into a
         Response object using `make_response`

    # This code will process each non-file field in the form
    fields = {}
    data = request.form.to_dict()
    for field in data:
        fields[field] = data[field]
        print('Processed field: %s' % field)

    # This code will process each file uploaded
    files = request.files.to_dict()
    for file_name, file in files.items():
        # Note: GCF may not keep files saved locally between invocations.
        # If you want to preserve the uploaded files, you should save them
        # to another location (such as a Cloud Storage bucket).
        print('Processed file: %s' % file_name)

    # Clear temporary directory
    for file_name in files:
        file_path = get_file_path(file_name)

    return "Done!"


require "functions_framework"

FunctionsFramework.http "http_form_data" do |request|
  # The request parameter is a Rack::Request object.
  # See

  # This Rack call parses multipart form data, returning the params as a hash.
  # The returned params hash includes an entry for each field. File uploads
  # are written to Tempfiles and represented by hashes, while plain fields are
  # represented by strings.
  params = request.POST

    params.each do |name, part|
      if part.is_a? Hash
        # Handle a file upload part by logging the md5 hash.
        md5 = Digest::MD5.hexdigest part[:tempfile].read
        file_name = part[:filename] "Processed file=#{file_name} md5=#{md5}"
        # Handle a non-file part by logging the value. "Processed field=#{name} value=#{part}"
    # Ensure that all Tempfile objects are closed and deleted. The Cloud
    # Functions runtime keeps temporary files in an in-memory file system,
    # so to lower memory usage it is good practice to clean up Tempfiles
    # explicitly rather than wait for object finalization.
    params.each_value do |part|
      part[:tempfile].close! if part.is_a? Hash

  # The HTTP response body.

Étapes suivantes

Pour rechercher et filtrer des exemples de code pour d'autres produits Google Cloud, consultez l'explorateur d'exemples Google Cloud.