vux-uploader这个图片上传插件,在一些项目中已经采用了。因为之前的前端ui都是用vux这套,所以理所当然也选择这个图片上传插件了。而且还提供一些可以进行定制化hook。
greedying/vux-uploader
其中最重要的代码uploader.vue
get_signature(body){
// 可以判断当前expire是否超过了当前时间, 如果超过了当前时间, 就重新取一下,3s 作为缓冲。
let timestamp = Date.parse(new Date()) / 1000;
let now = timestamp;
let expire = 0
if (expire < now + 3)
{
// let body = this.send_request()
console.log(body)
// let obj = eval ("(" + body + ")");
let obj = body
// console.log(obj);
this.uploadUrl = obj['host'];
this.oss.host = obj['host']
this.oss.policyBase64 = obj['policy']
this.oss.accessid = obj['accessid']
this.oss.signature = obj['signature']
this.oss.expire = parseInt(obj['expire'])
this.oss.callbackbody = obj['callback']
this.oss.key = obj['dir']
return true;
}
return false;
},
send_request(){
return new Promise((resolve, reject) => {
axios.get('/example/callBack').then((res) => {
resolve(res)
}).catch((err) => {
reject(err)
})
})
async uploadImage(formData){
// this.set_new_multipart_params();
let response = await this.send_request();
this.get_signature(response.data)
if (this.$vux && this.$vux.loading) {
this.$vux.loading.show('正在上传')
}
console.log(formData.get("file"));
let myformData = new window.FormData()
myformData.append("name",formData.get("file").name);
myformData.append("key",this.oss.key+"${filename}");
myformData.append("policy",this.oss.policyBase64);
myformData.append("OSSAccessKeyId",this.oss.accessid);
myformData.append("success_action_status",'200');
myformData.append("callback",this.oss.callbackbody);
myformData.append("signature",this.oss.signature);
myformData.append("file",formData.get("file"));
console.log(this.oss.host);
axios.post(this.oss.host, myformData,{headers:{}})
.then((response) => {
if (this.$vux && this.$vux.loading) {
this.$vux.loading.hide()
}
// let image = {url:this.oss.host+"/"+myformData.get("name")}
// let image = {url:this.oss.host+"/"+myformData.get("name")+"?x-oss-process=image/auto-orient,1/quality,q_10"}
let image = {url:this.oss.host+"/"+myformData.get("name")+"?x-oss-process=image/auto-orient,1/interlace,1/resize,m_lfit,w_200,h_200/watermark,text_5aSp6aaZ5p6c5Zut,color_ebe6e6,size_16,shadow_100,g_ne,x_10,y_10"}
this.images.push(image)
})
},
JavaScript客户端签名直传 通过这篇文章来实现客户端签名直传。 原来的例子中是采用servlet的方式来直传的,我进行了简单的spring-mvc改造。
/**
* @author : mjm
* @description :
* @date : 2019-07-22
*/
@Controller
@ExceptionListener
@RequestMapping(value = "/complain")
public class CallBackController {
@RequestMapping(value = "/callBack", method = RequestMethod.GET)
public ResponseEntity init() {
// callbackUrl为 上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
String callbackUrl = "http://example.com/api/v1/complain/callBack";
// String dir = "user-dir-prefix/"; // 用户上传文件时指定的前缀。
String dir = ""; // 用户上传文件时指定的前缀。
// OSSClient client = new OSSClient(endpoint, accessId, accessKey);
OSSClient client = OSSUtils.newInstant();
try {
long expireTime = 30;
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
Date expiration = new Date(expireEndTime);
PolicyConditions policyConds = new PolicyConditions();
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
String postPolicy = client.generatePostPolicy(expiration, policyConds);
byte[] binaryData = postPolicy.getBytes("utf-8");
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
String postSignature = client.calculatePostSignature(postPolicy);
Map<String, String> respMap = new LinkedHashMap<String, String>();
respMap.put("accessid", OSSUtils.getAccessKeyId());
respMap.put("policy", encodedPolicy);
respMap.put("signature", postSignature);
respMap.put("dir", dir);
respMap.put("host", OSSUtils.getUrl());
respMap.put("expire", String.valueOf(expireEndTime / 1000));
// respMap.put("expire", formatISO8601Date(expiration));
JSONObject jasonCallback = new JSONObject();
jasonCallback.put("callbackUrl", callbackUrl);
jasonCallback.put("callbackBody",
"filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
jasonCallback.put("callbackBodyType", "application/x-www-form-urlencoded");
String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes());
respMap.put("callback", base64CallbackBody);
JSONObject ja1 = JSONObject.fromObject(respMap);
// System.out.println(ja1.toString());
// response.setHeader("Access-Control-Allow-Origin", "*");
// response.setHeader("Access-Control-Allow-Methods", "GET, POST");
// response(request, response, ja1.toString());
HttpHeaders headers = new HttpHeaders();
headers.add("Access-Control-Allow-Origin", "*");
headers.add("Access-Control-Allow-Methods", "GET, POST");
return new ResponseEntity<>(
ja1.toString(), HttpStatus.OK);
} catch (Exception e) {
// Assert.fail(e.getMessage());
System.out.println(e.getMessage());
}
return new ResponseEntity<>(HttpStatus.OK);
}
@RequestMapping(value = "/callBack", method = RequestMethod.POST)
public void initPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
String ossCallbackBody = GetPostBody(request.getInputStream(),
Integer.parseInt(request.getHeader("content-length")));
System.out.println(ossCallbackBody);
boolean ret = VerifyOSSCallbackRequest(request, ossCallbackBody);
System.out.println("verify result : " + ret);
// System.out.println("OSS Callback Body:" + ossCallbackBody);
if (ret) {
response(request, response, "{\"Status\":\"OJBK\"}", HttpServletResponse.SC_OK);
// response(request, response, "{\"Status\":\"OJBK\",\"message\": \"result不是0时候的错误信息\",}", HttpServletResponse.SC_OK);
// response(request, response, "{ \n" +
// " result: 0,\n" +
// " message: \"result不是0时候的错误信息\",\n" +
// " data: {\n" +
// " url: \"http://image.url.com/image.png\"\n" +
// " }\n" +
// " }", HttpServletResponse.SC_OK);
} else {
response(request, response, "{\"Status\":\"verdify not ok\"}", HttpServletResponse.SC_BAD_REQUEST);
}
}
/**
* 服务器响应结果
*
* @param request
* @param response
* @param results
* @param status
* @throws IOException
*/
private void response(HttpServletRequest request, HttpServletResponse response, String results, int status)
throws IOException {
String callbackFunName = request.getParameter("callback");
response.addHeader("Content-Length", String.valueOf(results.length()));
if (callbackFunName == null || callbackFunName.equalsIgnoreCase(""))
response.getWriter().println(results);
else
response.getWriter().println(callbackFunName + "( " + results + " )");
response.setStatus(status);
response.flushBuffer();
}
/**
* 获取Post消息体
*
* @param is
* @param contentLen
* @return
*/
public String GetPostBody(InputStream is, int contentLen) {
if (contentLen > 0) {
int readLen = 0;
int readLengthThisTime = 0;
byte[] message = new byte[contentLen];
try {
while (readLen != contentLen) {
readLengthThisTime = is.read(message, readLen, contentLen - readLen);
if (readLengthThisTime == -1) {// Should not happen.
break;
}
readLen += readLengthThisTime;
}
return new String(message);
} catch (IOException e) {
}
}
return "";
}
/**
* 验证上传回调的Request
*
* @param request
* @param ossCallbackBody
* @return
* @throws NumberFormatException
* @throws IOException
*/
protected boolean VerifyOSSCallbackRequest(HttpServletRequest request, String ossCallbackBody)
throws NumberFormatException, IOException {
boolean ret = false;
String autorizationInput = new String(request.getHeader("Authorization"));
String pubKeyInput = request.getHeader("x-oss-pub-key-url");
byte[] authorization = BinaryUtil.fromBase64String(autorizationInput);
byte[] pubKey = BinaryUtil.fromBase64String(pubKeyInput);
String pubKeyAddr = new String(pubKey);
if (!pubKeyAddr.startsWith("http://gosspublic.alicdn.com/")
&& !pubKeyAddr.startsWith("https://gosspublic.alicdn.com/")) {
System.out.println("pub key addr must be oss addrss");
return false;
}
String retString = executeGet(pubKeyAddr);
retString = retString.replace("-----BEGIN PUBLIC KEY-----", "");
retString = retString.replace("-----END PUBLIC KEY-----", "");
String queryString = request.getQueryString();
String uri = request.getRequestURI();
String decodeUri = java.net.URLDecoder.decode(uri, "UTF-8");
String authStr = decodeUri;
if (queryString != null && !queryString.equals("")) {
authStr += "?" + queryString;
}
authStr += "\n" + ossCallbackBody;
ret = doCheck(authStr, authorization, retString);
return ret;
}
/**
* 验证RSA
*
* @param content
* @param sign
* @param publicKey
* @return
*/
public static boolean doCheck(String content, byte[] sign, String publicKey) {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = BinaryUtil.fromBase64String(publicKey);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
java.security.Signature signature = java.security.Signature.getInstance("MD5withRSA");
signature.initVerify(pubKey);
signature.update(content.getBytes());
boolean bverify = signature.verify(sign);
return bverify;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 获取public key
*
* @param url
* @return
*/
@SuppressWarnings({ "finally" })
public String executeGet(String url) {
BufferedReader in = null;
String content = null;
try {
// 定义HttpClient
@SuppressWarnings("resource")
DefaultHttpClient client = new DefaultHttpClient();
// 实例化HTTP方法
HttpGet request = new HttpGet();
request.setURI(new URI(url));
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
content = sb.toString();
} catch (Exception e) {
} finally {
if (in != null) {
try {
in.close();// 最后要关闭BufferedReader
} catch (Exception e) {
e.printStackTrace();
}
}
return content;
}
}