vue+thinkphp5.1实现阿里云oss文件上传(服务器签名上传)

发布时间 2023-10-14 23:05:30作者: 小枫同学

一、vue.js

<template>
  <div class="common-box">
    <el-upload
      class="upload-demo"
      drag
      :action="data.host"
      multiple
      :auto-upload="false"
      ref="upload"
      :data="data.data"
      :before-upload="getSign">
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
      <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
    </el-upload>
    <el-button type="primary" @click="upload">上传</el-button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      data: {
        host: '',
        data: {}
      }
    }
  },
  methods: {
    async getSign (file) {
      console.log(file)
      const res = await this.$http.get('tools/oss/upload/sn?name=' + file.name)
      if (res.status) {
        this.data.data = res.data
        this.data.host = res.data.host
      }
      return true
    },
    upload () {
      this.$refs.upload.submit()
    }
  },
  mounted () {

  }
}
</script>

<style lang='less' scoped>
</style>

二、sn.php

public function ossUploadSn()
{
    $request = request()->get();
    $id = '';          // 请填写您的AccessKeyId。
    $key = '';     // 请填写您的AccessKeySecret。
    // $host的格式为 bucketname.endpoint,请替换为您的真实信息。
    $host = 'http://xfstu-resources.oss-cn-hongkong.aliyuncs.com/';
    // $callbackUrl为上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实URL信息。
    $callbackUrl = 'https://api.muzifeng.top/test/php/callback.php';
    $dir = 'user-dir-prefix/';          // 用户上传文件时指定的前缀。

    $callback_param = array(
        'callbackBody' => 'filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}',
        'callbackBodyType' => "application/x-www-form-urlencoded"
    );
    $callback_string = json_encode($callback_param);

    $base64_callback_body = base64_encode($callback_string);
    $now = time();
    $expire = 50;  //设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问。
    $end = $now + $expire;
    $expiration = str_replace('+00:00', '.000Z', gmdate('c', $end));


    //最大文件大小.用户可以自己设置
    $condition = array(0 => 'content-length-range', 1 => 0, 2 => 1048576000);
    $conditions[] = $condition;

    // 表示用户上传的数据,必须是以$dir开始,不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录。
    $start = array(0 => 'starts-with', 1 => '$key', 2 => $dir);
    $conditions[] = $start;


    $arr = array('expiration' => $expiration, 'conditions' => $conditions);
    $policy = json_encode($arr);
    $base64_policy = base64_encode($policy);
    $string_to_sign = $base64_policy;
    $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $key, true));

    $response = [
        'name' => $request['name'],
        'key' => $dir . $request['name'],
        'policy' => $base64_policy,
        'OSSAccessKeyId' => $id,
        'success_action_status' => 200,
        'callback' => $base64_callback_body,
        'signature' => $signature,
        'host' => $host
    ];
    return JsonResponse::success($response);
}