1. 请求自己服务端,获取上传需要用到的参数(文件名、文件地址、签名等)
  2. 请求第三方,使用表单将文件和上传所需参数传给第三方(需要第三方的网址配置跨域)
  3. 请求服务端,告诉服务端,刚刚的文件上传成功(如果第三方服务支持回调通知,那么这一步不需要;如果服务端逻辑不关心这个文件是否上传成功,此步骤也可省略,严谨操作而言,如果第三方没有回调,需要有这一步操作)

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)相关推荐

  1. 分享一个react 图片上传组件 支持OSS 七牛云

    react-uplod-img 是一个基于 React antd组件的图片上传组件 支持oss qiniu等服务端自定义获取签名,批量上传, 预览, 删除, 排序等功能 需要 react 版本大于 v ...

  2. 微信 开发 图片 上传 阿里云 oss 服务器

    在做微信开发时,我需要将图片上传至阿里云OSS,思路是服务端下载微信图片再转存至OSS. wx.chooseImage({count: 1, // 默认9sizeType: ['original', ...

  3. 阿里云使用js 实现OSS图片上传、获取OSS图片列表、获取图片外网访问地址(读写权限私有、读写权限公共);...

    详情请参考:https://help.aliyun.com/document_detail/32069.html?spm=a2c4g.11186623.6.763.ZgC59a 或者https://h ...

  4. input file图片上传(使用OSS Javscrtipt 上传到服务器)以及图片裁剪(cropper.js)

    一.图片上传 (1)使用 <input type="file" accept="image/*" name="file" @chang ...

  5. (Java) 解决使用 base64编码 保存到本地的图片出现破损的问题。 另:将base64编码图片上传至本地/OSS。

    上周使用 base64 上传图片到OSS中的时候,发现保存的图片出现显示马赛克和图片破损打不开的情况.找了很久也没有出现问题,今天在找答案的时候,偶然间发现有个博主分享的内容完美的解决了我的问题(这里 ...

  6. 若依-vue图片上传本地改OSS前台以及后台-附带oss图片上传工具类

    阿丹: 在二次开发若依的过程中发现若依的图片上传的默认的是在本地,在spring-vue版本中,如果要将平台上线那么就需要考虑这个问题,要使用fastdfs或者oss来完成代替本地的图片上传. 本篇文 ...

  7. html读取oss_阿里云使用js 实现OSS图片上传、获取OSS图片列表(示例代码)

    详情请参考:https://help.aliyun.com/document_detail/32069.html?spm=a2c4g.11186623.6.763.ZgC59a 或者https://h ...

  8. 阿里OSS对象存储,实现图片上传代码;

    一.注册阿里云账号,购买OSS服务 获取 : 连接区域地址endpoint :需要存储的bucketName:图片保存路径picLocation :连接keyId:accessKeyId :连接秘钥a ...

  9. antd的联级选择器异步调用编辑回显_react-uplod-img 是一个基于 React antd组件的图片上传组件...

    react-uplod-img 是一个基于 React antd组件的图片上传组件 支持oss qiniu等服务端自定义获取签名,批量上传, 预览, 删除, 图片精确的尺寸限制 排序等功能 需要 re ...

最新文章

  1. php的一些基本概念梳理
  2. 看完这篇,Oracle数据库运维不用愁
  3. ABAP如何生成UUID
  4. 母亲的牛奶 Mother's Milk
  5. svn数据仓库配置,权限配置
  6. 《面向对象软件工程》笔记(一)
  7. linux系统有几个系统盘,linux操作系统的分区有哪些种类?各分区主要作用是什么?...
  8. 人类最强运载火箭诞生!马斯克吹的牛再次兑现!
  9. PHP stdClass to Array and Array to stdClass – stdClass Object
  10. 【JDK源码分析】StringBuilder、StringBuilder、String、AbstractStringBuilder源码解析
  11. 在 ubuntu 下优雅的使用 Sublime Text 3 写 Python
  12. document.ready 与 onload 的区别
  13. Git------GitHub官网
  14. yourphp超出20记录自动删除
  15. Cadence Allegro学习之PCB封装库的导出
  16. 网络通信协议基础(ISIS)——入门
  17. 数据库MySQL学习——内含34道MySQL练习题及答案
  18. 近代光学系统设计概论学习笔记-第四章双胶合和双分离消色差物镜
  19. PDF文档太大怎么办?
  20. Python机器学习建模的标准流程(特征工程+建模调参+模型评估+全流程可视化)

热门文章

  1. Matlab 命令大全
  2. angularjscheckbox全选_AngularJS实现全选反选功能
  3. win10电脑用lp地址连接共享打印机
  4. Virtualbox文件拖放问题
  5. 在线使用Python通过染色体id+位置查询基因名列表
  6. 携程网首页案例-移动端
  7. 深度学习中的FLOPs是什么?如何计算的?
  8. Android中kotlin Flow的资源浪费/ANR问题
  9. 程显峰:应届毕业生简历的常见问题
  10. 终结盗号密码生命的技术方案