上傳文件是咱們在前端開發中常常遇到的一個問題。最近在作某項目管理後臺的時候,須要將輪播圖上傳至七牛雲。之前在Vue裏面作過相似的功能,可是在Angular中使用一樣的方法發現行不通。javascript
此篇文章主要介紹在Angular組件中如何上傳圖片至七牛雲。在其餘前端框架(好比React、Vue等)中步驟3一樣適用,只是步驟1和步驟2有所區別。下面具體介紹在Angular組件中上傳圖片至七牛雲的步驟。css
在index.html中引入七牛js-sdk文件中的壓縮文件,這裏咱們引入qiniu.min.js。html
【注意】在引入qiniu.min.js以前,咱們須要引入plupload上傳組件。前端
Plupload是一款由著名的web編輯器TinyMCE團隊開發的上傳組件,簡單易用且功能強大。html5
這裏咱們引入plupload.full.min.js和plupload的zh_CN.js文件。java
在index中引入qiniu和plupload的js代碼以下圖所示:git
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<!--上傳圖片 七牛JS-SDK-->
<script src="//cdn.staticfile.org/plupload/2.1.9/plupload.full.min.js"></script>
<script src="//cdn.bootcss.com/plupload/2.1.9/i18n/zh_CN.js"></script>
<script src="//cdn.staticfile.org/qiniu-js-sdk/1.0.14-beta/qiniu.min.js"></script>
</body>
</html>
複製代碼
以上引入js文件的方式咱們這裏均採用CDN的方式引入,也能夠將這些文件下載到本地,而後用引入文件的方式引入。github
咱們也能夠先在工程的src目錄下創建一個文件夾lib,而後將plupload.full.min.js和qiniu.min.js下載至本地放到該目錄下。以下圖所示: web
而後經過在angualr.json中進行相應的配置,便可引入須要依賴的js文件。代碼以下圖所示:json
"scripts": [
"./src/lib/plupload.full.min.js",
"./src/lib/qiniu.min.js"
]
複製代碼
作這個功能的時候一直卡在了這一步,找了半天緣由是由於沒有在angular組件中進行聲明。所以要想使用依賴的js文件,首先得在組件中進行聲明,代碼以下圖所示:
declare var Qiniu: any;
declare var plupload: any;
複製代碼
經過閱讀 七牛JavaScript SDK文檔,須要作以下初始化:
// 上傳添加時的輪播圖
uploadBanner(): void {
const _this = this;
_this.uploadProgress = 0;
_this.bannerUrl = '';
const optionImg = {
runtimes: 'html5,flash,html4', // 上傳模式,依次退化
browse_button: 'uploadbanner', // 上傳選擇的點選按鈕,必需
// 在初始化時,uptoken,uptoken_url,uptoken_func三個參數中必須有一個被設置
// 切若是提供了多個,其優先級爲uptoken > uptoken_url > uptoken_func
// 其中uptoken是直接提供上傳憑證,uptoken_url是提供了獲取上傳憑證的地址,若是須要定製獲取uptoken的過程則能夠設置uptoken_func
// uptoken : '', // uptoken是上傳憑證,由其餘程序生成
// uptoken_url: '//cloud-api.changhong.io', // Ajax請求uptoken的Url,強烈建議設置(服務端提供)
uptoken_func: function(file) { // 在須要獲取uptoken時,該方法會被調用
// _this.uploadProgress = 0;
return _this.uptoken;
},
get_new_uptoken: true, // 設置上傳文件的時候是否每次都從新獲取新的uptoken
// downtoken_url: '/downtoken',
// Ajax請求downToken的Url,私有空間時使用,JS-SDK將向該地址POST文件的key和domain,服務端返回的JSON必須包含url字段,url值爲該文件的下載地址
// unique_names: true, // 默認false,key爲文件名。若開啓該選項,JS-SDK會爲每一個文件自動生成key(文件名)
// save_key: true, // 默認false。若在服務端生成uptoken的上傳策略中指定了sava_key,則開啓,SDK在前端將不對key進行任何處理
domain: 'http://pqe96fvpl.bkt.clouddn.com', // bucket域名,下載資源時用到,必需
//container: 'container', // 上傳區域DOM ID,默認是browser_button的父元素
max_file_size: '100mb', // 最大文件體積限制
flash_swf_url: 'https://cdn.bootcss.com/plupload/2.1.9/Moxie.swf', // 引入flash,相對路徑
max_retries: 3, // 上傳失敗最大重試次數
//dragdrop: true, // 開啓可拖曳上傳
//drop_element: 'container', // 拖曳上傳區域元素的ID,拖曳文件或文件夾後可觸發上傳
chunk_size: '4mb', // 分塊上傳時,每塊的體積
auto_start: true, // 選擇文件後自動上傳,若關閉須要本身綁定事件觸發上傳
init: {
'FilesAdded': function(up, files) {
plupload.each(files, function(file) {
if (file.type === 'image/jpg' || file.type === 'image/jpeg' || file.type === 'image/png') {
_this.uploadProgress = 0;
} else {
_this.nzMessageService.success('僅支持類型爲.jpg,.png的文件');
up.removeFile(file);
return false;
}});
},
'BeforeUpload': function(up, file) {
// 每一個文件上傳前,處理相關的事情
},
'UploadProgress': function(up, file) {
// 每一個文件上傳時,處理相關的事情
_this.uploadProgress = file.percent;
},
'FileUploaded': function (up, file, info) {
// 每一個文件上傳成功後,處理相關的事情
// 其中info是文件上傳成功後,服務端返回的json,形式如:
// {
// "hash": "Fh8xVqod2MQ1mocfI4S4KpRL6D98",
// "key": "gogopher.jpg"
// }
// 查看簡單反饋
const domain = up.getOption('domain');
const res = JSON.parse(info.response);
const sourceLink = domain + '/' + res.key; // 獲取上傳成功後的文件的Url
_this.bannerUrl = sourceLink;
},
'Error': function (up, err, errTip) {
// 上傳出錯時,處理相關的事情
// swal('', errTip, 'error');
},
'Key': function (up, file) {
// 若想在前端對每一個文件的key進行個性化處理,能夠配置該函數
// 該配置必需要在unique_names: false,save_key: false時才生效
const key = 'portal/banners/' + file.name;
// do something with key here
return key;
}
// 'UploadComplete': function() {
// 隊列文件處理完畢後,處理相關的事情
// },
// 'Key': function(up, file) {
// 若想在前端對每一個文件的key進行個性化處理,能夠配置該函數
//該配置必需要在unique_names: false,save_key: false時才生效
//
//var key = "";
//do something with key here
//return key
// }
}
};
this.uploaderAdd = Qiniu.uploader(optionImg);
}
複製代碼
browse_button屬性的值須要在模板文件中,添加對應的id選擇器的節點,好比當設置browse_button的值爲'uploadbanner'的時候,則模板文件中需添加以下的按鈕:
<button nz-button id="uploadeditbanner"><i nz-icon nzType="upload"></i><span>上傳</span></button>
複製代碼
根據七牛官方文檔:JS-SDK 依賴服務端頒發 token,爲了安全,token 建議經過網絡從服務端獲取。後端服務應提供一個 URL 地址,供 SDK 初始化使用,前端經過 Ajax 請求該地址後得到 upToken。
前端有如下3種方式獲取upToken:
uptoken : '', // uptoken是上傳憑證,由其餘程序生成
uptoken_url: '', // Ajax請求uptoken的Url,強烈建議設置(服務端提供)
uptoken_func: function(file) { }, //在須要獲取uptoken時,該方法會被調用
複製代碼
這3種方式具體用哪一種需根據後端服務提供哪一種獲取upToken的方式決定。
domain地址須要從後端編寫接口的人告知。
若是咱們須要限制文件的類型,好比咱們只容許上傳.jpg、.jpeg、.png格式的文件,則須要在FilesAdded函數中添加以下代碼:
plupload.each(files, function(file) {
if (file.type === 'image/jpg' || file.type === 'image/jpeg' || file.type === 'image/png') {
_this.uploadProgress = 0;
} else {
_this.nzMessageService.success('僅支持類型爲.jpg、.jpeg、.png的文件');
up.removeFile(file);
return false;
}
});
複製代碼
若是須要顯示上傳的進度條,則在UploadProgress函數中添加相應代碼。
_this.uploadProgress = file.percent;
複製代碼
經過file參數的percent屬性獲取到上傳進度的百分比,而後賦值給須要在前端頁面上進行顯示的變量。
上傳完成後,要獲取上傳的圖片的url地址,則須要在FileUploaded函數中,添加以下代碼:
const domain = up.getOption('domain');
const res = JSON.parse(info.response);
const sourceLink = domain + '/' + res.key; // 獲取上傳成功後的文件的Url
複製代碼
最終效果以下圖所示: