全部产品
Search
文档中心

Object Storage Service:Unggah objek menggunakan URL pra-tandatangan yang dihasilkan dengan OSS SDK untuk PHP 1.0

更新时间:Nov 05, 2025

Secara default, daftar kontrol akses (ACL) dari sebuah objek Object Storage Service (OSS) bersifat pribadi. Hanya pemilik objek yang memiliki izin untuk mengunggah objek ke bucket. Anda dapat menggunakan OSS SDK untuk PHP untuk menghasilkan URL pra-tandatangan dan membagikannya kepada pengguna agar mereka dapat mengunggah objek. Saat menghasilkan URL pra-tandatangan, Anda dapat menentukan periode validitasnya untuk membatasi jangka waktu selama objek dapat diakses. Selama periode validitasnya, pengguna dapat menggunakan URL tersebut untuk mengunggah objek ke bucket berkali-kali. Jika objek diunggah beberapa kali, objek yang diunggah mungkin tertimpa. Setelah periode validitas URL pra-tandatangan berakhir, pengguna tidak lagi dapat menggunakannya untuk mengunggah objek. Dalam hal ini, Anda harus menghasilkan URL pra-tandatangan baru.

Catatan

  • Dalam topik ini, titik akhir publik wilayah Tiongkok (Hangzhou) digunakan. Untuk mengakses OSS dari layanan Alibaba Cloud lainnya di wilayah yang sama, gunakan titik akhir internal. Untuk detail tentang wilayah dan titik akhir yang didukung, lihat Wilayah dan titik akhir.

  • Dalam topik ini, kredensial akses diperoleh dari variabel lingkungan. Untuk informasi lebih lanjut tentang cara mengonfigurasi kredensial akses, lihat Konfigurasikan kredensial akses (PHP SDK V1).

  • Untuk menghasilkan URL pra-tandatangan untuk unggahan objek, Anda harus memiliki izin oss:PutObject. Untuk informasi lebih lanjut, lihat Lampirkan kebijakan kustom ke Pengguna RAM.

    Catatan

    Saat menggunakan OSS SDK untuk PHP untuk menghasilkan URL pra-tandatangan, SDK menggunakan algoritma tertentu berdasarkan informasi kunci yang disimpan di komputer lokal untuk menghitung tanda tangan dan menambahkan tanda tangan tersebut ke URL untuk memastikan validitas dan keamanan URL. Operasi yang dilakukan untuk menghitung tanda tangan dan membuat URL diselesaikan di sisi klien. Anda tidak perlu mengirim permintaan ke server melalui jaringan. Dengan cara ini, pemanggil tidak perlu diberi izin khusus untuk menggunakan OSS SDK untuk PHP menghasilkan URL pra-tandatangan. Namun, untuk mengizinkan pengguna pihak ketiga melakukan operasi terkait pada sumber daya yang diotorisasi oleh URL pra-tandatangan, Anda harus memastikan bahwa pemanggil yang memanggil operasi API untuk menghasilkan URL pra-tandatangan memiliki izin yang sesuai.

  • Dalam topik ini, URL pra-tandatangan V4 dengan periode validitas hingga tujuh hari digunakan. Untuk informasi lebih lanjut, lihat (Direkomendasikan) Tanda tangan V4 dalam URL pra-tandatangan.

  • URL pra-tandatangan yang dihasilkan menggunakan kode sampel berikut mungkin berisi tanda tambah (+). Dalam hal ini, ganti tanda tambah (+) dalam URL dengan %2B. Jika tidak, URL pra-tandatangan mungkin tidak dapat digunakan untuk mengakses objek seperti yang diharapkan.

  • Untuk menghasilkan URL pra-tandatangan yang digunakan untuk mengakses sumber daya melalui HTTPS, atur protokol di titik akhir ke HTTPS.

Proses

Gambar berikut menunjukkan cara menggunakan URL pra-tandatangan yang mengizinkan permintaan HTTP PUT untuk mengunggah objek ke OSS.

Kode sampel

  1. Pemilik objek menghasilkan URL pra-tandatangan yang mengizinkan permintaan HTTP PUT.

    <?php
    if (is_file(__DIR__ . '/../autoload.php')) {
        require_once __DIR__ . '/../autoload.php';
    }
    if (is_file(__DIR__ . '/../vendor/autoload.php')) {
        require_once __DIR__ . '/../vendor/autoload.php';
    }
    
    use OSS\OssClient;
    use OSS\Core\OssException;
    use OSS\Http\RequestCore;
    use OSS\Http\ResponseCore;
    use OSS\Credentials\EnvironmentVariableCredentialsProvider;
    
    // Dapatkan kredensial akses dari variabel lingkungan. Sebelum menjalankan kode sampel, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah dikonfigurasi.
    $provider = new EnvironmentVariableCredentialsProvider();
    // Tentukan titik akhir wilayah tempat bucket berada. Misalnya, jika bucket berada di wilayah Tiongkok (Hangzhou), atur titik akhir ke https://oss-cn-hangzhou.aliyuncs.com. 
    $endpoint = "yourEndpoint";
    // Tentukan nama bucket. 
    $bucket= "examplebucket";
    // Tentukan jalur lengkap objek. Jangan sertakan nama bucket dalam jalur lengkap objek. 
    $object = "exampleobject.txt";
    // Atur periode validitas URL pra-tandatangan menjadi 600 detik. Nilai maksimum: 32400. 
    $timeout = 600;
    try {
        $config = array(  
            "provider" => $provider,
            "endpoint" => $endpoint,
            'signatureVersion'=>OssClient::OSS_SIGNATURE_VERSION_V4,
            "region"=> "cn-hangzhou"
        );
        $ossClient = new OssClient($config);
        // Hasilkan URL pra-tandatangan. 
        $signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "PUT");
        print_r($signedUrl);
    } catch (OssException $e) {
        printf(__FUNCTION__ . ": FAILED\n");
        printf($e->getMessage() . "\n");
        return;
    }           
  2. Gunakan URL pra-tandatangan yang mengizinkan permintaan HTTP PUT untuk mengunggah objek.

    curl

    curl -X PUT -T /path/to/local/file "https://exampleobject.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T083238Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************%2F20241112%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-signature=ed5a******************************************************"

    Java

    import org.apache.http.HttpEntity;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpPut;
    import org.apache.http.entity.FileEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import java.io.*;
    import java.net.URL;
    import java.util.*;
    
    public class SignUrlUpload {
        public static void main(String[] args) throws Throwable {
            CloseableHttpClient httpClient = null;
            CloseableHttpResponse response = null;
    
            // Ganti <signedUrl> dengan URL pra-tandatangan. 
            URL signedUrl = new URL("<signedUrl>");
    
            // Tentukan jalur lengkap file lokal yang ingin Anda unggah. Jika jalur file lokal tidak ditentukan, file lokal akan diunggah dari jalur proyek tempat program sampel milik. 
            String pathName = "C:\\Users\\demo.txt";
    
            try {
                HttpPut put = new HttpPut(signedUrl.toString());
                System.out.println(put);
                HttpEntity entity = new FileEntity(new File(pathName));
                put.setEntity(entity);
                httpClient = HttpClients.createDefault();
                response = httpClient.execute(put);
    
                System.out.println("Kode status:"+response.getStatusLine().getStatusCode());
                if(response.getStatusLine().getStatusCode() == 200){
                    System.out.println("Objek diunggah menggunakan pustaka.");
                }
                System.out.println(response.toString());
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                response.close();
                httpClient.close();
            }
        }
    }       

    Go

    package main
    
    import (
    	"fmt"
    	"io"
    	"net/http"
    	"os"
    )
    
    func uploadFile(signedUrl, filePath string) error {
    	// Buka file lokal.
    	file, err := os.Open(filePath)
    	if err != nil {
    		return fmt.Errorf("Tidak dapat membuka file lokal: %w", err)
    	}
    	defer file.Close()
    
    	// Buat klien HTTP.
    	client := &http.Client{}
    
    	// Buat permintaan PUT.
    	req, err := http.NewRequest("PUT", signedUrl, file)
    	if err != nil {
    		return fmt.Errorf("Gagal membuat permintaan: %w", err)
    	}
    
    	// Kirim permintaan.
    	resp, err := client.Do(req)
    	if err != nil {
    		return fmt.Errorf("Gagal mengirim permintaan:: %w", err)
    	}
    	defer resp.Body.Close()
    
    	// Baca tanggapan.
    	body, err := io.ReadAll(resp.Body)
    	if err != nil {
    		return fmt.Errorf("Gagal membaca permintaan: %w", err)
    	}
    
    	fmt.Printf("Kode status: %d\n", resp.StatusCode)
    	if resp.StatusCode == 200 {
    		fmt.Println("Objek diunggah menggunakan pustaka.")
    	}
    	fmt.Println(string(body))
    
    	return nil
    }
    
    func main() {
    	// Ganti <signedUrl> dengan URL pra-tandatangan. 
    	signedUrl := "<signedUrl>"
    
    	// Tentukan jalur lengkap file lokal yang ingin Anda unggah. Jika jalur file lokal tidak ditentukan, file lokal akan diunggah dari jalur proyek tempat program sampel milik. 
    	filePath := "C:\\Users\\demo.txt"
    
    	err := uploadFile(signedUrl, filePath)
    	if err != nil {
    		fmt.Println("Terjadi kesalahan: ", err)
    	}
    }
    

    python

    import requests
    
    def upload_file(signed_url, file_path):
        try:
            # Buka file lokal yang ingin Anda unggah.
            with open(file_path, 'rb') as file:
                # Kirim permintaan PUT untuk mengunggah file lokal.
                response = requests.put(signed_url, data=file)
         
            print(f"Kode status: {response.status_code}")
            if response.status_code == 200:
                print("Objek diunggah menggunakan pustaka.")
            print(response.text)
     
        except Exception as e:
            print(f"Terjadi kesalahan: {e}")
    
    if __name__ == "__main__":
        # Ganti <signedUrl> dengan URL pra-tandatangan yang dihasilkan. 
        signed_url = "<signedUrl>"
        
        # Tentukan jalur lengkap file lokal. Jika jalur file lokal tidak ditentukan, file lokal akan diunggah dari jalur proyek tempat program sampel milik. 
        file_path = "C:\\Users\\demo.txt"
    
        upload_file(signed_url, file_path)
    

    Node.js

    const fs = require('fs');
    const axios = require('axios');
    
    async function uploadFile(signedUrl, filePath) {
        try {
            // Buat aliran baca.
            const fileStream = fs.createReadStream(filePath);
            
            // Kirim permintaan PUT untuk mengunggah file lokal.
            const response = await axios.put(signedUrl, fileStream, {
                headers: {
                    'Content-Type': 'application/octet-stream' // Tentukan parameter Content-Type.
                }
            });
    
            console.log(`Kode status: ${response.status}`);
            if (response.status === 200) {
                console.log("Objek diunggah menggunakan pustaka.");
            }
            console.log(response.data);
        } catch (error) {
            console.error(`Terjadi kesalahan: ${error.message}`);
        }
    }
    
    // Tentukan fungsi utama.
    (async () => {
        // Ganti <signedUrl> dengan URL pra-tandatangan. 
        const signedUrl = '<signedUrl>';
        
        // Tentukan jalur lengkap file lokal yang ingin Anda unggah. Jika jalur file lokal tidak ditentukan, file lokal akan diunggah dari jalur proyek tempat program sampel milik. 
        const filePath = 'C:\\Users\\demo.txt';
    
        await uploadFile(signedUrl, filePath);
    })();

    browser.js

    Penting

    Saat mengunggah objek menggunakan Browser.js dan URL pra-tandatangan, kesalahan 403 SignatureNotMatch yang menunjukkan ketidaksesuaian tanda tangan mungkin terjadi. Ini biasanya disebabkan oleh penambahan otomatis header permintaan Content-Type oleh browser, yang tidak ditentukan saat URL pra-tandatangan dihasilkan. Untuk mencegah kesalahan ini, pastikan header Content-Type ditentukan saat menghasilkan URL pra-tandatangan.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Contoh Unggah File</title>
    </head>
    <body>
        <h1>Contoh Unggah File</h1>
    
        <! -- Pilih File -->
        <input type="file" id="fileInput" />
        <button id="uploadButton">Unggah File</button>
    
        <script>
            // Ganti <signedUrl> dengan URL pra-tandatangan yang dihasilkan di Langkah 1. 
            const signedUrl = "<signedUrl>"; 
    
    
            document.getElementById('uploadButton').addEventListener('click', async () => {
                const fileInput = document.getElementById('fileInput');
                const file = fileInput.files[0];
    
                if (!file) {
                    alert('Silakan pilih file untuk diunggah.');
                    return;
                }
    
                try {
                    await upload(file, signedUrl);
                    alert('File berhasil diunggah!');
                } catch (error) {
                    console.error('Kesalahan saat unggah:', error);
                    alert('Unggah gagal: ' + error.message);
                }
            });
    
            /**
             * Unggah file ke OSS.
             * @param {File} file - File yang akan diunggah.
             * @param {string} presignedUrl - URL pra-tandatangan.
             */
            const upload = async (file, presignedUrl) => {
                const response = await fetch(presignedUrl, {
                    method: 'PUT',
                    body: file,  // Unggah seluruh file.
                });
    
                if (!response.ok) {
                    throw new Error(`Unggah gagal, status: ${response.status}`);
                }
    
                console.log('File berhasil diunggah');
            };
        </script>
    </body>
    </html>

    C#

    using System.Net.Http.Headers;
    
    // Tentukan jalur lengkap file lokal yang ingin Anda unggah. Jika jalur file lokal tidak ditentukan, file lokal akan diunggah dari jalur proyek tempat program sampel milik. 
    var filePath = "C:\\Users\\demo.txt";
    // Ganti <signedUrl> dengan URL pra-tandatangan.
    var presignedUrl = "<signedUrl>";
    
    // Buat klien HTTP dan aliran file lokal.
    using var httpClient = new HttpClient(); 
    using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
    using var content = new StreamContent(fileStream);
                
    // Buat permintaan PUT.
    var request = new HttpRequestMessage(HttpMethod.Put, presignedUrl);
    request.Content = content;
    
    // Kirim permintaan.
    var response = await httpClient.SendAsync(request);
    
    // Proses tanggapan.
    if (response.IsSuccessStatusCode)
    {
        Console.WriteLine($"Diunggah! Kode Status: {response.StatusCode}");
        Console.WriteLine("Header Tanggapan:");
        foreach (var header in response.Headers)
        {
            Console.WriteLine($"{header.Key}: {string.Join(", ", header.Value)}");
        }
    }
    else
    {
        string responseContent = await response.Content.ReadAsStringAsync();
        Console.WriteLine($"Unggah Gagal! Kode Status: {response.StatusCode}");
        Console.WriteLine("Isi tanggapan: " + responseContent);
    }

    C++

    #include <iostream>
    #include <fstream>
    #include <curl/curl.h>
    
    void uploadFile(const std::string& signedUrl, const std::string& filePath) {
        CURL *curl;
        CURLcode res;
    
        curl_global_init(CURL_GLOBAL_DEFAULT);
        curl = curl_easy_init();
    
        if (curl) {
            // Tentukan URL pra-tandatangan.
            curl_easy_setopt(curl, CURLOPT_URL, signedUrl.c_str());
    
            // Atur metode permintaan ke PUT.
            curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
    
            // Buka file lokal.
            FILE *file = fopen(filePath.c_str(), "rb");
            if (!file) {
                std::cerr << "Tidak dapat membuka file: " << filePath << std::endl;
                return;
            }
    
            // Periksa ukuran file lokal.
            fseek(file, 0, SEEK_END);
            long fileSize = ftell(file);
            fseek(file, 0, SEEK_SET);
    
            // Tentukan ukuran file lokal.
            curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fileSize);
    
            // Tentukan handle file input.
            curl_easy_setopt(curl, CURLOPT_READDATA, file);
    
            // Jalankan permintaan.
            res = curl_easy_perform(curl);
    
            if (res != CURLE_OK) {
                std::cerr << "curl_easy_perform() gagal: " << curl_easy_strerror(res) << std::endl;
            } else {
                long httpCode = 0;
                curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
                std::cout << "Kode status: " << httpCode << std::endl;
    
                if (httpCode == 200) {
                    std::cout << "Objek diunggah menggunakan pustaka jaringan." << std::endl;
                }
            }
    
            // Tutup file lokal.
            fclose(file);
    
            // Bersihkan handle cURL.
            curl_easy_cleanup(curl);
        }
    
        curl_global_cleanup();
    }
    
    int main() {
        // Ganti <signedUrl> dengan URL pra-tandatangan. 
        std::string signedUrl = "<signedUrl>";
    
        // Tentukan jalur lengkap file lokal yang ingin Anda unggah. Jika jalur file lokal tidak ditentukan, file lokal akan diunggah dari jalur proyek tempat program sampel milik. 
        std::string filePath = "C:\\Users\\demo.txt";
    
        uploadFile(signedUrl, filePath);
    
        return 0;
    }
    

    Android

    package com.example.signurlupload;
    
    import android.os.AsyncTask;
    import android.util.Log;
    
    import java.io.DataOutputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class SignUrlUploadActivity {
    
        private static final String TAG = "SignUrlUploadActivity";
    
        public void uploadFile(String signedUrl, String filePath) {
            new UploadTask().execute(signedUrl, filePath);
        }
    
        private class UploadTask extends AsyncTask<String, Void, String> {
    
            @Override
            protected String doInBackground(String... params) {
                String signedUrl = params[0];
                String filePath = params[1];
    
                HttpURLConnection connection = null;
                DataOutputStream dos = null;
                FileInputStream fis = null;
    
                try {
                    URL url = new URL(signedUrl);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("PUT");
                    connection.setDoOutput(true);
                    connection.setRequestProperty("Content-Type", "application/octet-stream");
    
                    fis = new FileInputStream(filePath);
                    dos = new DataOutputStream(connection.getOutputStream());
    
                    byte[] buffer = new byte[1024];
                    int length;
    
                    while ((length = fis.read(buffer)) != -1) {
                        dos.write(buffer, 0, length);
                    }
    
                    dos.flush();
                    dos.close();
                    fis.close();
    
                    int responseCode = connection.getResponseCode();
                    Log.d(TAG, "Kode status: " + responseCode);
    
                    if (responseCode == 200) {
                        Log.d(TAG, "Objek diunggah menggunakan pustaka.");
                    }
    
                    return "Objek diunggah. Kode status: " + responseCode;
    
                } catch (IOException e) {
                    e.printStackTrace();
                    return "Unggah gagal: " + e.getMessage();
                } finally {
                    if (connection != null) {
                        connection.disconnect();
                    }
                }
            }
    
            @Override
            protected void onPostExecute(String result) {
                Log.d(TAG, result);
            }
        }
    
        public static void main(String[] args) {
            SignUrlUploadActivity activity = new SignUrlUploadActivity();
            // Ganti <signedUrl> dengan URL pra-tandatangan. 
            String signedUrl = "<signedUrl>";
            // Tentukan jalur lengkap file lokal yang ingin Anda unggah. Jika jalur file lokal tidak ditentukan, file lokal akan diunggah dari jalur proyek tempat program sampel milik. 
            String filePath = "C:\\Users\\demo.txt";
            activity.uploadFile(signedUrl, filePath);
        }
    }
    

Skenario lain

Hasilkan URL pra-tandatangan yang mencakup header versionId

Berikut adalah contoh kode sampel tentang cara menghasilkan URL pra-tandatangan yang mencakup header versionId:

<?php
  if (is_file(__DIR__ . '/../autoload.php')) {
  require_once __DIR__ . '/../autoload.php';
  }
  if (is_file(__DIR__ . '/../vendor/autoload.php')) {
  require_once __DIR__ . '/../vendor/autoload.php';
  }

use OSS\OssClient;
use OSS\Core\OssException;
use OSS\Http\RequestCore;
use OSS\Http\ResponseCore;
use OSS\Credentials\EnvironmentVariableCredentialsProvider;

// Dapatkan kredensial akses dari variabel lingkungan. Sebelum menjalankan kode sampel, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah dikonfigurasi. 
$provider = new EnvironmentVariableCredentialsProvider();
// Tentukan titik akhir wilayah tempat bucket berada. Misalnya, jika bucket berada di wilayah Tiongkok (Hangzhou), atur titik akhir ke https://oss-cn-hangzhou.aliyuncs.com. 
$endpoint = "yourEndpoint";
// Tentukan nama bucket. 
$bucket= "examplebucket";
// Tentukan jalur lengkap objek. Jangan sertakan nama bucket dalam jalur lengkap objek. 
$object = "exampleobject.txt";
// Atur periode validitas URL pra-tandatangan menjadi 600 detik. Nilai maksimum: 32400. 
$timeout = 600;
try{
  $config = array(
      "provider" => $provider,
      "endpoint" => $endpoint,
      "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
      "region"=> "cn-hangzhou"
  );
  $ossClient = new OssClient($config);
  $options = array(
      // Tentukan ID versi objek. 
      $ossClient::OSS_VERSION_ID=>"CAEQEhiBgIDmgPf8mxgiIDA1YjZlNDIxY2ZmMzQ1MmU5MTM1Y2M4Yzk4NjIx****"
  );
  // Hasilkan URL pra-tandatangan. 
  $signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "GET", $options);
  print_r($signedUrl);
} catch(OssException $e) {
  printf($e->getMessage() . "\n");
}