3***@qq.com
3***@qq.com
  • 发布:2019-04-28 11:45
  • 更新:2021-06-16 20:45
  • 阅读:9127

请问uni.uploadFile接口怎么改成put请求,或者uni.request怎么传file

分类:uni-app

我这边有个需求是在前端把图片直接上传阿里云oss(只需要兼容h5,ios,安卓),必须是用put请求上传file格式的文件,但是uploadFile发起的是post请求,如果直接用request的话data无法定义为file,只能是object,这个情况就很尴尬。

然后用uni.chooseImage在h5获取的格式是blob,我试过把blob转成file再调用插件市场封装的请求上传,但是最后的请求体还是blob,并且转file的方法无法兼容app端。

跪求解决办法,能否把uploadFile方法改成put请求。

2019-04-28 11:45 负责人:无 分享
已邀请:
2***@qq.com

2***@qq.com

为什么要限定上传的请求方式呢,不理解,我用drf 做后台,要求像这种某字段更新操作,只可以用put方法。希望官方能把这个功能改成可以自定义请求方式。

初学者123

初学者123 - 80后IT男

面临同样的问题。从后台获得的签名,指定是通过 put 方式上传,而 uni.uploadFile 的指定方式是 post,导致使用签名无法成功上传。试了在 formData 中更改 method 方式,没有起效。我是这样写的:
formData:{
'_method': 'put',
},

报错:Cannot Post

初学者123

初学者123 - 80后IT男

最终成功了,参照我的方法:
https://ask.dcloud.net.cn/article/38747

  • 1***@qq.com

    有使用阿里OSS sts这种 put方法上传的吗


    2021-06-16 17:52

3***@qq.com

3***@qq.com (作者)

跪求。。

zhangdaren

zhangdaren - 小程序转uniapp工具:https://ext.dcloud.net.cn/plugin?id=2656

首先,谢邀~

下面是我上传到阿里视频点播所使用的部分代码,仅供参考,
我使用plus.gallery.pick来获取的视频文件,至于uni.chooseImage并没有使用过,且目前做的app就真的只做app,不考虑其他,所以附上代码希望能给楼主帮助。

另:blob文件实际就是图片文件,只是文件名变了而已,不信把blob改成Jpg或png就变成图片了。

var wt = plus.nativeUI.showWaiting();  
var task = plus.uploader.createUpload(this.server, {  
		method: "POST"  
	},  
	(t, status) => { //上传完成  
		console.log("t" + JSON.stringify(t) + "  status: " + status);  
		if (status == 200) {  
			wt.setTitle("上传成功:" + t.responseText);  
		} else {  
			wt.setTitle("上传失败:" + status);  
		}  
	}  
);  
console.log("task " + task);  
var suffix1 = this.get_suffix(this.fname); //文件后缀  例如   .jpg  
var keyname = this.dir + new Date().getTime() + suffix1;  
  
this.testName = keyname;  
  
//按照之前说明的参数类型,按顺序添加参数  
keyname = data.fileName;  
this.signature = data.signature;  
var accessKeyId = data.accessKeyId;  
var token = data.token;  
var policy = data.policy;  
///  
task.addData("key", keyname);  
task.addData("policy", policy);  
task.addData("OSSAccessKeyId", accessKeyId);  
task.addData("success_action_status", "200");  
task.addData("signature", this.signature);  
task.addData("x-oss-security-token", token);  
var f = this.files[0];  //这里的文件路径  
task.addFile(f.path, {  
	key: "file",  
	name: "file",  
	mime: "video/mp4"  
});  
  
task.addEventListener("statechanged", onStateChanged, false);  
task.start();  
  
// 监听上传任务状态  
function onStateChanged(upload, status) {  
	switch (upload.state) {  
		case 2:  
			wt.setTitle("已连接服务器");  
			break;  
		case 3:  
			let percent = upload.uploadedSize / upload.totalSize;  
			console.log("上传进度: " + percent)  
			wt.setTitle("已上传" + parseInt(percent) + "%");  
			break;  
		case 4:  
			wt.setTitle("上传完成");  
			console.log("upload  " + JSON.stringify(upload), "  status", status);  
  
			setTimeout(() => {  
				wt.close();  
			}, 2000);  
			break;  
		default:  
			break;  
	}  
}
7***@qq.com

7***@qq.com

我做图片上传的时候先转base64再压缩base64 再用request请求 强烈不推荐 很慢 很卡

最后再uploadFile from-data 是POST

uni.chooseImage({  
					count: 99,  
					success: function(e){  
						var imagePathArr = e.tempFilePaths  
						for(let i=0; i<imagePathArr.length;i++){  
							// _self.value.push(imagePathArr[i])  
							uni.uploadFile({  
								url:'FileMangment/UploadFile',  
								fileType: 'image',  
								formData:{  
									upDirectory:'/Files/Measure'  
								},  
								filePath: imagePathArr[i],   
								name: 'fileBase',  
								success: function(res){  
									console.log(res)  
									}  
								},  
								fail: function(res){  
									console.log(res)  
								}  
							})  
						}  
						  
					}  
				})
5***@qq.com

5***@qq.com

我记得put请求本质还是post请求。在使用ajax和form表单做put或delete请求时,把请求方式设置为post,然后在请求参数中添加额外的参数 "_method":"PUT" 这样就可以。我觉得你的这个uploadFile接口也同样道理,可以这样试一下

梅子酒2020

梅子酒2020

有没有搞定啊? 一样的问题

1***@qq.com

1***@qq.com

一样问题 太难了 OSS

初学者123

初学者123 - 80后IT男

阿里云以前也成功了,后来由于上传速度未达标而放弃了。代码如下:

前端代码我做成了公共方法来调用

//获取阿里云的预签名信息  
function get_presigned_url(file_path, file_name, callback){  
	return new Promise((resolve, reject)=>{  
		uni.request({  
			url: '',   //后台接口,就是下面的php代码的请求路径  
			method: 'GET',  
			success: (res) => {  
				resolve(res.data)  
			}  
		})  
	}).then(res=>{  
		let policy = res.policy;  
		let signature = res.signature;  
		let accessid = res.accessid;  
		let host = res.host;  
		uni.uploadFile({  
			url: host,  
			filePath: file_path,  
			name: 'file',  
			formData: {  
			  'key': file_name,  
			  'policy': policy,  
			  'OSSAccessKeyId': accessid,  
			  'signature': signature,  
			  'success_action_status': '200',  
			},  
			success:(res)=>{  
				callback(res);  
			}  
		})  
	})  
} ```  
  
PHP代码,就是前端请求的接口:  
/**  
 * 获取阿里云 OSS 预签名进行前端上传操作  
 */  
public function get_signature(){  
    $id= '';          // 请填写你的AccessKeyId。  
    $key= '';     // 请填写你的AccessKeySecret。  
    // $host的格式为 bucketname.endpoint,请替换为你的真实信息。  
    $host = '';    
    // $callbackUrl为上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实URL信息。  
    $callbackUrl = 'http://公网ip地址:8080/aliyun-oss-appserver-php/php/callback.php';  
    $dir = '';          // 用户上传文件时指定的前缀。  
	  
    $callback_param = array('callbackUrl'=>$callbackUrl, '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 = 30;  //设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问。  
    $end = $now + $expire;  
    $expiration = $this->gmt_iso8601($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 = array();  
    $response['accessid'] = $id;  
    $response['host'] = $host;  
    $response['policy'] = $base64_policy;  
    $response['signature'] = $signature;  
    $response['expire'] = $end;  
    $response['callback'] = $base64_callback_body;  
    $response['dir'] = $dir;  // 这个参数是设置用户上传文件时指定的前缀。  
    echo json_encode($response);  
} ```

该问题目前已经被锁定, 无法添加新回复