图片上传第三方(ucloud、oss)
- 请求自己服务端,获取上传需要用到的参数(文件名、文件地址、签名等)
- 请求第三方,使用表单将文件和上传所需参数传给第三方(需要第三方的网址配置跨域)
请求服务端,告诉服务端,刚刚的文件上传成功(如果第三方服务支持回调通知,那么这一步不需要;如果服务端逻辑不关心这个文件是否上传成功,此步骤也可省略,严谨操作而言,如果第三方没有回调,需要有这一步操作)
ucloud:
不支持回调,如需回调,需要自己通知服务端
https://docs.ucloud.cn/api/ufile-api/post_file
oss(阿里云):
阿里云,支持回调,在第一步,服务端返回正确的callback地址,在第二步带给第三方,第三方即可直接回调我们的服务端
https://help.aliyun.com/document_detail/31988.html?spm=a2c4g.11186623.2.40.47e460e8pGyHP6#reference-smp-nsw-wdb
1、3流程为普通的api请求,针对第2步上传不同的第三方,给出一下示例:
ucloud:
网页相关:
// 假设第一步请求自己的服务端,返回如下结构的参数
// data = {
// file_name: {file_name},
// signature: {signature}
// };// php 中的配置,一般为bucket的域名地址
// $config['ucloud']['upload_api'] = 'yiziruwo.cn-sh2.ufileos.com';// 此处需注意,ucloud有些域名地址支持https上传,有些不支持,这里写的时候需要和后端确认是用http还是https
var url = 'https://<?php echo $config['ucloud']['upload_api'] ?>';var xmlhttp;if (window.XMLHttpRequest) {//IE7+, Firefox, Chrome, Opera, Safarixmlhttp = new XMLHttpRequest;//针对某些特定版本的mozillar浏览器的bug进行修正if (xmlhttp.overrideMimeType) {xmlhttp.overrideMimeType('text/xml');};
} else if (window.ActiveXObject){//IE6, IE5xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
};if(xmlhttp.upload){//2.回调函数xmlhttp.onreadystatechange = function(e){if(xmlhttp.readyState == 4){if(xmlhttp.status == 200){var json = eval('(' + xmlhttp.responseText + ')');console.log(json);}else{console.log(xmlhttp.responseText);}}};//3.设置连接信息xmlhttp.open("POST",url,true);//4.发送数据,开始和服务器进行交互// 如下的FormData中,字段都为必传,且必须按以下的先后顺序添加到表单中(否则第三方会报错)// FileName传第一步,我们自己后端返回数据中的文件名filename// Authorization传第一步,我们自己后端返回数据中的前面signature// Content-Type,传js的api,fileReader读取到的文件类型(确保文件格式的正确,如果图片文件不传图片类型的这个字段,可能会导致第三方的文件地址返回的文件内容不是图片格式)// file,传文件的指针进去即可,一般有如下两种方法获取(选其一即可)// js方法:// var source = document.getElementById('J_file_input');// var file = source.files[0];// jquery方法:// var source = $('#J_file_input').get(0);// var file = source.files[0];var formdata = new FormData();formdata.append("FileName", data.file_name);formdata.append("Authorization", data.signature);formdata.append("Content-Type", file_type);formdata.append("file", file);xmlhttp.send(formdata);
}
React Native:
/*** 上传ucloud文件* @param filePath 文件路径* @param fileName ucloud文件id* @param signature ucloud文件签名* @param fileType 文件类型*/// 这里的filePath,为图片的路径,安卓为file://开头,ios为/开头,可能需要单独包装下,选图插件返回的都是以/开头的路径(具体参考小世界系列代码),这里只贴出核心的上传第三方代码async uploadUcloudFile(filePath: string, fileName: string, signature: string, fileType: FileType) {await this.handleThrowNetError()return RNFetchBlob.fetch('POST', getUcloudEndpoint(),{'Content-Type': 'multipart/form-data',},[{ name: 'FileName', data: fileName },{ name: 'Authorization', data: signature },{name: 'file',filename: this.getFileName(fileType),type: this.getMimeType(fileType),data: RNFetchBlob.wrap(filePath)}]).uploadProgress({ interval: 250 }, (sent, total) => {// 这里可以监听到上传的进度if (fileType === FileType.Video) {eventConfig.emitUploadEvent(filePath, sent, total)}}).then(async resp => {if (resp.respInfo.status >= 400) {let error = await resp.json()return this.handleThrowError('POST', {status: resp.respInfo.status,error: error})} else {return resp}}).catch(e => {this.handleErrorLog(getUcloudEndpoint(), {}, JSON.stringify(e))throw e})
}
小程序:
wx.uploadFile({url: 'https://yiziruwo.cn-sh2.ufileos.com',filePath: this.data.file,name: 'file',formData: {"FileName": res1.data.file_name,"Authorization": res1.data.signature,"Content-Type": "image/png"},success(res2) {},fail(err2) {}
})
vue:
export function uploadFile(file, params, key) {console.log('params: ', params)console.log('file: ', file)return new Promise((resolve, reject) =>new Promise((resImg, rejImg) => {const img = new Image()img.onload = function() {resImg(img)}img.src = URL.createObjectURL(file)}).then((res) => {console.log('img: ', res.height, res.width)const createParams = {type: 1,width: res.width,height: res.height,mime_type: params.file_type}if (params.sort) createParams.sort = params.sortcreateUploadFile(createParams).then(fileInfo => {console.log('createUploadFile success:', fileInfo)const fileForm = new FormData()fileForm.append('FileName', fileInfo.file_id)fileForm.append('Authorization', fileInfo.signature)fileForm.append('Content-Type', params.file_type)const nameArr = file.name.split('.')const fileType = nameArr[nameArr.length - 1]const newFile = new File([file], fileInfo.file_id + '.' + fileType, { type: file.type })fileForm.append('file', newFile)console.log('fileForm:', fileForm)uploadToThirdService(fileForm).then(thirdResp => {console.log('uploadToThirdService success:', thirdResp)informUploadFileSuccess({file_id: fileInfo.file_id}).then(informResp => {console.log('informUploadFileSuccess success:', informResp)resolve(Object.assign({}, { fileInfo: fileInfo }, { thirdResp: thirdResp }, { informResp: informResp }, { key: key }, { imgInfo: {type: file.type,size: file.size,name: file.name,width: createParams.width,height: createParams.height}}))}).catch(error3 => {console.log('informUploadFileSuccess error:', error3)reject({desc: 'informUploadFileSuccess error',error: error3})})}).catch(error2 => {console.log('uploadToThirdService error:', error2)reject({desc: 'uploadToThirdService error',error: error2})})}).catch(error1 => {console.log('createUploadFile error:', error1)reject({desc: 'createUploadFile error',error: error1})})}))
}// 创建文件
export function createUploadFile(params) {return request({url: 'xxx', // 自己服务器接口地址method: 'post',data: params})
}// 上传文件到ucloud
export function uploadToThirdService(params) {return uploadRequest({url: '/', // 远程地址method: 'post',headers: { 'Content-Type': 'multipart/form-data' },data: params})
}// 通知文件上传成功
export function informUploadFileSuccess(params) {return request({url: '/backend/file',method: 'put',data: params})
}
oss
网页:
// 假设第一步请求自己的服务端,返回如下结构的参数
// data = {
// "file_id": {file_id},
// "signature": {signature},
// "file_url": {file_url},
// "policy": {policy},
// "callback": {callback},
// "host": {host},
// "accessid": {accessid}
// };
// file_id: 文件id
// signature: 文件签名
// file_url: 文件url
// policy: 表单域
// callback: 加密后的上传回调
// host: 上传的地址
// accessid: 上传公钥var url = data.host;var xmlhttp;if (window.XMLHttpRequest) {//IE7+, Firefox, Chrome, Opera, Safarixmlhttp = new XMLHttpRequest;//针对某些特定版本的mozillar浏览器的bug进行修正if (xmlhttp.overrideMimeType) {xmlhttp.overrideMimeType('text/xml');};
} else if (window.ActiveXObject){//IE6, IE5xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
};if(xmlhttp.upload){//2.回调函数xmlhttp.onreadystatechange = function(e){if(xmlhttp.readyState == 4){if(xmlhttp.status == 200){var json = eval('(' + xmlhttp.responseText + ')');console.log(json);}else{console.log(xmlhttp.responseText);}}};//3.设置连接信息xmlhttp.open("POST",url,true);//4.发送数据,开始和服务器进行交互// file,传文件的指针进去即可,一般有如下两种方法获取(选其一即可)// js方法:// var source = document.getElementById('J_file_input');// var file = source.files[0];// jquery方法:// var source = $('#J_file_input').get(0);// var file = source.files[0];var formdata = new FormData();formdata.append("key", data.file_id);formdata.append("policy", data.policy);formdata.append("OSSAccessKeyId", data.accessid);formdata.append("success_action_status", "200");formdata.append("callback", data.callback);formdata.append("signature", data.signature);formdata.append("file", file);xmlhttp.send(formdata);
}
React Native:
/*** 上传oss文件* @param filePath 文件路径* @param fileType 文件类型* @param uploadOptions 后端返回的用户上传的参数*/// 这里的filePath,为图片的路径,安卓为file://开头,ios为/开头,可能需要单独包装下,选图插件返回的都是以/开头的路径(具体参考拉蜂代码),这里只贴出核心的上传第三方代码async uploadOssFile(filePath: string, fileType: FileType, uploadOptions: any) {let uploadDatas = [{ name: 'key', data: uploadOptions.file_id}, { name: 'policy', data: uploadOptions.policy },{ name: 'OSSAccessKeyId', data: uploadOptions.accessid },{ name: 'success_action_status', data: '200' },{ name: 'callback', data: uploadOptions.callback },{ name: 'signature', data: uploadOptions.signature },{name: 'file',filename: this.getFileName(fileType),type: this.getMimeType(fileType),data: RNFetchBlob.wrap(filePath)}]// 如果是内测环境(我们自己的服务端是在外网访问不到环境的话,那么不能使用callback回调参数,否则会报错)if (configureStore().appStore.runtimeEnv === RuntimeEnv.dev) {uploadDatas = [{ name: 'key', data: uploadOptions.file_id}, // + this.getFileSuffix(fileType) },{ name: 'policy', data: uploadOptions.policy },{ name: 'OSSAccessKeyId', data: uploadOptions.accessid },{ name: 'success_action_status', data: '200' },// { name: 'callback', data: uploadOptions.callback },{ name: 'signature', data: uploadOptions.signature },{name: 'file',filename: this.getFileName(fileType),type: this.getMimeType(fileType),data: RNFetchBlob.wrap(filePath)}]}await this.handleThrowNetError()return RNFetchBlob.fetch('POST', uploadOptions.host,{'Content-Type': 'multipart/form-data',},uploadDatas).then(async resp => {console.log('upload then:', resp)if (resp.respInfo.status === 200) { // 200 代表成功,其它都失败,前面success_action_status配置了200的return resp} else {return this.handleThrowError('POST', {status: resp.respInfo.status,error: resp.data})}}).catch(e => {this.handleErrorLog(uploadOptions.host, {}, JSON.stringify(e))console.log('upload error:', e)throw e})
}
PHP模拟表单上传(用于ueditor编辑器传图部分)
// php使用表单上传的时候,需要用@文件路径,或者new CURLFile(文件路径)的方式,才能带上文件private function upload_file($uploadOptions, $file_content, $file_type, $file_path){$url = $uploadOptions['host'];if (class_exists('\CURLFile')) { // php 5.5以上$file_data = new CURLFile($file_path);} else {$file_data = '@'.realpath($file_path).";type=".$file_type.";filename=".$uploadOptions['file_id'];}$data = array('key' => $uploadOptions['file_id'],'policy' => $uploadOptions['policy'],'OSSAccessKeyId' => $uploadOptions['accessid'],'success_action_status' => '200','callback' => $uploadOptions['callback'],'signature' => $uploadOptions['signature'],'file' => $file_data);$curl = curl_init();curl_setopt($curl, CURLOPT_URL,$url); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: multipart/form-data")); curl_setopt($curl, CURLOPT_POST, 1);curl_setopt($curl, CURLOPT_POSTFIELDS, $data); curl_setopt($curl, CURLOPT_HEADER, 1); curl_setopt($curl, CURLOPT_TIMEOUT, 120);curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);$result = curl_exec($curl);$info = curl_getinfo($curl);$error_no = curl_errno($curl);$error_str = curl_error($curl); curl_close($curl);// var_dump($result);// var_dump($info);// var_dump($error_no);// var_dump($error_str);if($info["http_code"] == 200){$return_arr = Array('code' => 1,'data' => $uploadOptions);}else{$return_arr = Array('code' => 0,'data' => Array("time" => date("Y-m-d H:i:s"),'url' => $url,"http code" => $info["http_code"],'body' => json_encode($result),"Curl error num" => $error_no,'Curl error' => $error_str));}return $return_arr;
}
图片上传第三方(ucloud、oss)相关推荐
- 分享一个react 图片上传组件 支持OSS 七牛云
react-uplod-img 是一个基于 React antd组件的图片上传组件 支持oss qiniu等服务端自定义获取签名,批量上传, 预览, 删除, 排序等功能 需要 react 版本大于 v ...
- 微信 开发 图片 上传 阿里云 oss 服务器
在做微信开发时,我需要将图片上传至阿里云OSS,思路是服务端下载微信图片再转存至OSS. wx.chooseImage({count: 1, // 默认9sizeType: ['original', ...
- 阿里云使用js 实现OSS图片上传、获取OSS图片列表、获取图片外网访问地址(读写权限私有、读写权限公共);...
详情请参考:https://help.aliyun.com/document_detail/32069.html?spm=a2c4g.11186623.6.763.ZgC59a 或者https://h ...
- input file图片上传(使用OSS Javscrtipt 上传到服务器)以及图片裁剪(cropper.js)
一.图片上传 (1)使用 <input type="file" accept="image/*" name="file" @chang ...
- (Java) 解决使用 base64编码 保存到本地的图片出现破损的问题。 另:将base64编码图片上传至本地/OSS。
上周使用 base64 上传图片到OSS中的时候,发现保存的图片出现显示马赛克和图片破损打不开的情况.找了很久也没有出现问题,今天在找答案的时候,偶然间发现有个博主分享的内容完美的解决了我的问题(这里 ...
- 若依-vue图片上传本地改OSS前台以及后台-附带oss图片上传工具类
阿丹: 在二次开发若依的过程中发现若依的图片上传的默认的是在本地,在spring-vue版本中,如果要将平台上线那么就需要考虑这个问题,要使用fastdfs或者oss来完成代替本地的图片上传. 本篇文 ...
- html读取oss_阿里云使用js 实现OSS图片上传、获取OSS图片列表(示例代码)
详情请参考:https://help.aliyun.com/document_detail/32069.html?spm=a2c4g.11186623.6.763.ZgC59a 或者https://h ...
- 阿里OSS对象存储,实现图片上传代码;
一.注册阿里云账号,购买OSS服务 获取 : 连接区域地址endpoint :需要存储的bucketName:图片保存路径picLocation :连接keyId:accessKeyId :连接秘钥a ...
- antd的联级选择器异步调用编辑回显_react-uplod-img 是一个基于 React antd组件的图片上传组件...
react-uplod-img 是一个基于 React antd组件的图片上传组件 支持oss qiniu等服务端自定义获取签名,批量上传, 预览, 删除, 图片精确的尺寸限制 排序等功能 需要 re ...
最新文章
- php的一些基本概念梳理
- 看完这篇,Oracle数据库运维不用愁
- ABAP如何生成UUID
- 母亲的牛奶 Mother's Milk
- svn数据仓库配置,权限配置
- 《面向对象软件工程》笔记(一)
- linux系统有几个系统盘,linux操作系统的分区有哪些种类?各分区主要作用是什么?...
- 人类最强运载火箭诞生!马斯克吹的牛再次兑现!
- PHP stdClass to Array and Array to stdClass – stdClass Object
- 【JDK源码分析】StringBuilder、StringBuilder、String、AbstractStringBuilder源码解析
- 在 ubuntu 下优雅的使用 Sublime Text 3 写 Python
- document.ready 与 onload 的区别
- Git------GitHub官网
- yourphp超出20记录自动删除
- Cadence Allegro学习之PCB封装库的导出
- 网络通信协议基础(ISIS)——入门
- 数据库MySQL学习——内含34道MySQL练习题及答案
- 近代光学系统设计概论学习笔记-第四章双胶合和双分离消色差物镜
- PDF文档太大怎么办?
- Python机器学习建模的标准流程(特征工程+建模调参+模型评估+全流程可视化)