官方教程地址:/document_detail/383950.html?spm=a2c4g.383952.0.0
这篇文章主要是指出官方教程没有说明的地方
后端代码
并非是完全完全不需要后端的参与。需要后端生成凭证,防止秘钥泄露
这里是官方的说明文档:使用STS临时访问凭证访问OSS
按照官方说法来到第五步
第五步只提供了Java代码,并且PHP的SDK中说明,缺少了一个步骤
PHP的SDK中说明需要引入如下SDK
composer require alibabacloud/sts-0401
这里还缺少一个SDK的引入,如下
composer require "alibabacloud/client"
使用Thinkphp的实现代码如下:
namespace app\api\controller;use OSS\Core\OssException;use OSS\OssClient;use Qiniu\Auth;use Qiniu\Storage\UploadManager;use think\Config;use think\Controller;use think\Debug;use think\Request;use think\Session;use AlibabaCloud\Client\AlibabaCloud;use AlibabaCloud\Client\Exception\ClientException;use AlibabaCloud\Client\Exception\ServerException;class Upload extends Controller{/*** 阿里云Sts凭证*/public function getStsToken(){$accessKeyId = "你自己在阿里云设置的RAM的accessKeyId"; // 你自己的$accessKeySecret = "你自己在阿里云设置的RAM的accessKeySecret"; // 你自己的$roleArn = "你自己在阿里云设置的RAM的roleArn"; // 角色访问控制 RoleArn,你在设置的$roleSessionName = "ramosstest"; // 临时凭证名称,随意AlibabaCloud::accessKeyClient($accessKeyId, $accessKeySecret)->regionId('cn-hongkong')->asDefaultClient();try {$result = AlibabaCloud::rpc()->product('Sts')->scheme('https') // https | http->version('-04-01')->action('AssumeRole')->method('POST')->host('')->options(['query' => ['RegionId' => "cn-hongkong",'RoleArn' => $roleArn,'RoleSessionName' => $roleSessionName,],])->request();echo "<pre>";return print_r($result->toArray());} catch (ClientException $e) {return json($e->getErrorMessage());} catch (ServerException $e) {return json($e->getErrorMessage());}}}
前端代码
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><title>Document</title></head><body><button id="upload">上传</button><input id="file" type="file" /><!--导入SDK文件--><scripttype="text/javascript"src="/aliyun-oss-sdk-6.16.0.min.js"></script><script type="text/javascript">const client = new OSS({region: 'oss-cn-hongkong',accessKeyId: 'STS.后端代码调用生成的accessKeyId',accessKeySecret: '后端代码调用生成的accessKeySecret',stsToken: '后端代码调用生成的SecurityToken',bucket: 'kdlbook-hongkong'});let data;const upload = document.getElementById("upload");async function putObject (data, originalFilename, originalFileExtension) {try {// 我这里做了一些小的变更,采用的原始文件名+随机字符串来防止文件重复,当然也可以采用日期的格式let newFilename = `${originalFilename}_${Math.random()}${originalFileExtension}`;const result = await client.put(`${newFilename}`,data);alert("上传结果完成,返回文件名为:"+result.name);console.log(result);} catch (e) {console.log(e);}}upload.addEventListener("click", () => {data = document.getElementById("file").files[0];let originalFilename = data.name.substring(0, data.name.lastIndexOf('.'));let originalFileExtension = data.name.substring(data.name.lastIndexOf('.'));putObject(data, originalFilename, originalFileExtension);});</script></body></html>
需要注意的问题
官方文档里面有一个上传回调,但是这里并不需要,是同步回调的,虽然F12里面没有看到接口的返回值由于是JS请求,存在跨域问题,需要设置跨域请求。官方文档:/document_detail/31870.html?spm=a2c4g.375302.0.i3You have no right to access this object because of bucket acl.
这个需要开启访问权限,可以F12查看返回内容类似如下
<Error> <Code>AccessDenied</Code> <Message>You have no right to access this object because of bucket acl.</Message> <RequestId>622FF5149849B43239F0C519</RequestId> <HostId>bucketbylz.oss-cn-</HostId> </Error>
这种情况是文件已经上传成功了,只是访问权限有限制。
文档地址:/document_detail/100676.html?spm=a2c4g.450754.0.i2#concept-blw-yqm-2gb