场景
在微信服务号中开发上传图片功能
环境
后端 php yii2 前端javscript
遇到的问题
1.https 域 下前端处理base64为图片,苹果不支持。
2.七牛的fech接口很坑,有些数据不能存储,随机性的成功。
思路
1.通过微信的接口,调取手机的拍照和选取相册很方便可以设置选择几张和原图和缩略图,然后上传到微信的服务>器,返回一个media_id发送到后端,通过微信的文件媒体接口获取数据(数据token只存在两个小时),然后通过php
处理成base64位数据,上传到七牛,七牛返回链接存储在本地。
2.前端处理图片到七牛返回发到后端
前端处理
distant_view) {
echo '';
}else {
echo '';
}
?>
上传到七牛前端处理
注意 网站使用了https,苹果手机不能处理。
/**
* 上传64位编码到七牛
* @param [type] data [description]
* @return [type] [description]
*/
function putb64(data){
var pic = data;
var token = $('#token').val();
var url = "https://upload.qiniu.com/putb64/-1";
var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function(){
if (xhr.readyState==4){
var str =JSON.parse(xhr.responseText)
var srcImg = 'https://obf949end.qnssl.com/'+str.key;
$('#distant-click-img').attr('src',srcImg);
saveImageInfo(srcImg);
}
}
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.setRequestHeader("Authorization", "UpToken "+token);
xhr.send(pic);
}
后端处理图片上传到七牛
七牛有点坑,说明很不明确,处理个图片到七牛,找到两个接口,fetch 和 pubtb64
fetch 不稳定总是失败,不知道是不是跨域或者拦截,感觉不可靠。最终又改成了pubtb64位处理的
后端处理代码
自己在开发的过程中,各种百度,谷歌,很少有给全的代码,都靠自己去猜。在这里贴上全部代码,节省大家时间。
注释尽量加全,把所有的都集中在这里
/**
* 把图片存在服务器上面
* @return [type] [description]
*/
public function actionSaveDistantImgData()
{
Yii::$app->response->format = Response::FORMAT_JSON;
$request = Yii::$app->request;
$data = $request->post();
$img = $data['img'];
$id = $data['id'];
// 获取七牛的token
$token = self::GetUploadToken();
$upToken = $token['token'];
// 获取微信的 access_token
$weixin_token = \DockerEnv::get('WEIXIN_TOKEN');
$appid = \DockerEnv::get('WEIXIN_APP_ID');
$secret = \DockerEnv::get('WEIXIN_APP_SECRET');
$url_get = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$secret;
$json=$this->curlGet($url_get);
$weixin_token = json_decode($json);
$weixin_token=$weixin_token->access_token;
// 从微信服务器下载
$str = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=".$weixin_token."&media_id=".$img;
// 把从微信获得的数据用七牛上传到服务器上面
$access_key = \DockerEnv::get('QINIU_ACCESS_KEY');
$secret_key = \DockerEnv::get('QINIU_SECRET_KEY');
$this->request_by_curl($remote_server,$post_string,$upToken);
$strr = file_get_contents($str);
$fetch =base64_encode($strr);
$imggg = $this->request_by_curl('http://upload.qiniu.com/putb64/-1',$fetch,$upToken);
$imgs = json_decode(trim($imggg),true);
$imgss = $imgs['hash'];
$imgUrl = 'https://obf949end.qnssl.com/'.$imgss.'?imageslim';
// 把远景数据存在试管表里面
$test_tube = TestTube::findOne($id);
$test_tube->distant_view = $imgUrl;
$test_tube->save();
// 把远景图片存在藏匿者表里
$solid_sneak = SolidSneak::find()->where(['test_tube_id' => $id])->one();
$solid_sneak->distant_view = $imgUrl;
$solid_sneak->updated_at = time();
if ($solid_sneak->save()) {
return ['status' => 1,'data' => '图片上传成功'];
}
return ['status' => 0,'data' => '图片上传失败'];
}
其他调用方法
public function curlGet($url){
$ch = curl_init();
$header = "Accept-Charset: utf-8";
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
// curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$temp = curl_exec($ch);
return $temp;
}
public function send($url, $header = '') {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HEADER,0);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_POST, 1);
$con = curl_exec($curl);
if ($con === false) {
echo 'CURL ERROR: ' . curl_error($curl);
} else {
return $con;
}
}
public function urlsafe_base64_encode($str){
$find = array("+","/");
$replace = array("-", "_");
return str_replace($find, $replace, base64_encode($str));
}
public function request_by_curl($remote_server,$post_string,$upToken) {
$headers = array();
$headers[] = 'Content-Type:image/png';
$headers[] = 'Authorization:UpToken '.$upToken;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$remote_server);
//curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER ,$headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
/**
* generate_access_token
*
* @desc 签名运算
* @param string $access_key
* @param string $secret_key
* @param string $url
* @param array $params
* @return string
*/
public function generate_access_token($access_key, $secret_key, $url, $params = ''){
$parsed_url = parse_url($url);
$path = $parsed_url['path'];
$access = $path;
if (isset($parsed_url['query'])) {
$access .= "?" . $parsed_url['query'];
}
$access .= "\n";
if($params){
if (is_array($params)){
$params = http_build_query($params);
}
$access .= $params;
}
$digest = hash_hmac('sha1', $access, $secret_key, true);
return $access_key.':'.$this->urlsafe_base64_encode($digest);
}
public function base64EncodeImage ($image_file) {
$base64_image = '';
$image_info = getimagesize($image_file);
$image_data = fread(fopen($image_file, 'r'), filesize($image_file));
$base64_image = 'data:' . $image_info['mime'] . ';base64,' . chunk_split(base64_encode($image_data));
return $base64_image;
}