云开发是目前不少人在开发小程序时的选择,随着业务的增长,开发者也开始追求在更多的平台使用云开发。
今天,我们来看一看,如何在网页中直接使用云开发的 HTTP API 上传文件。
业务流程说明
由于云开发的存储使用的是腾讯云的对象存储 COS,因此,在上传时,存在一个上传流程的问题。具体的上传流程我绘制了一个时序图,你可以通过这个时序图来了解具体的上传流程。
具体实现
接下来我们来实现一下具体的上传步骤,主要来说,有以下三步:
1. 获取 Access Token
首先,我们需要获取 Access Token,这里我们需要用到微信官方文档的 getAccessToken
这个接口,已经小程序的 AppID 和 Secret 。 Appid 和 Secret 可以在小程序后台的开发设置中获取,这里不再赘述。
由于 Access Token 不允许在前端进行获取,需要大家根据自己的语言编写代码获取 Token ,并发送到前端。这里我给几个常见语言的例子
Java
你需要将下方的 APPID 和 SECRET 替换为你自己的 APPID 和 SECRET
import java.io.IOException;
import org.apache.http.client.fluent.*;
public class SendRequest
{
public static void main(String[] args) {
sendRequest();
}
private static void sendRequest() {
// 获取 Code (GET )
try {
// Create request
Content content = Request.Get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET")
// Fetch request and return content
.execute().returnContent();
// Print content
System.out.println(content);
}
catch (IOException e) { System.out.println(e); }
}
}
PHP
你需要将下方的 APPID 和 SECRET 替换为你自己的 APPID 和 SECRET
<?php
// get cURL resource
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET');
// set method
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
// return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// send the request and save response to $response
$response = curl_exec($ch);
// stop if fails
if (!$response) {
die('Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch));
}
echo 'HTTP Status Code: ' . curl_getinfo($ch, CURLINFO_HTTP_CODE) . PHP_EOL;
echo 'Response Body: ' . $response . PHP_EOL;
// close curl resource to free up system resources
curl_close($ch);
Ruby
你需要将下方的 APPID 和 SECRET 替换为你自己的 APPID 和 SECRET
require 'net/http'
require 'net/https'
# 获取 Code (GET )
def send_request
uri = URI('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET')
# Create client
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
# Create Request
req = Net::HTTP::Get.new(uri)
# Fetch Request
res = http.request(req)
puts "Response HTTP Status Code: #{res.code}"
puts "Response HTTP Response Body: #{res.body}"
rescue StandardError => e
puts "HTTP Request failed (#{e.message})"
end
2. 获取 COS 上传参数
当我们拿到了 Access Token 以后,就可以向云开发的接口发送请求,获取 COS 的上传参数了。同样,这个接口也需要在服务端请求。
需要注意的是,这个接口有三个参数,其中的 access token 需要放在 url 里,另外两个参数需要放在 post 的 body 里。
具体可以参考下面的代码,这里我用的参数如下:
{
"env": "rcn",
"path": "testfile"
}
Java
这里将 Token 替换为上一个环节中生成的 Token
import java.io.IOException;
import org.apache.http.client.fluent.*;
import org.apache.http.entity.ContentType;
public class SendRequest
{
public static void main(String[] args) {
sendRequest();
}
private static void sendRequest() {
// 调用上传接口 (POST )
try {
// Create request
Content content = Request.Post("https://api.weixin.qq.com/tcb/uploadfile?access_token=TOKEN")
// Add headers
.addHeader("Content-Type", "application/json; charset=utf-8")
// Add body
.bodyString("{\"env\": \"rcn\",\"path\": \"testfile\"}", ContentType.APPLICATION_JSON)
// Fetch request and return content
.execute().returnContent();
// Print content
System.out.println(content);
}
catch (IOException e) { System.out.println(e); }
}
}
PHP
这里将 Token 替换为上一个环节中生成的 Token
<?php
// get cURL resource
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, 'https://api.weixin.qq.com/tcb/uploadfile?access_token=TOKEN');
// set method
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
// return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// set headers
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json; charset=utf-8',
]);
// json body
$json_array = [
'env' => 'rcn',
'path' => 'testfile'
];
$body = json_encode($json_array);
// set body
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
// send the request and save response to $response
$response = curl_exec($ch);
// stop if fails
if (!$response) {
die('Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch));
}
echo 'HTTP Status Code: ' . curl_getinfo($ch, CURLINFO_HTTP_CODE) . PHP_EOL;
echo 'Response Body: ' . $response . PHP_EOL;
// close curl resource to free up system resources
curl_close($ch);
Ruby
这里将 Token 替换为上一个环节中生成的 Token
require 'net/http'
require 'net/https'
require 'json'
# 调用上传接口 (POST )
def send_request
uri = URI('https://api.weixin.qq.com/tcb/uploadfile?access_token=TOKEN')
# Create client
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
dict = {
"env" => "rcn",
"path" => "testfile"
}
body = JSON.dump(dict)
# Create Request
req = Net::HTTP::Post.new(uri)
# Add headers
req.add_field "Content-Type", "application/json; charset=utf-8"
# Set body
req.body = body
# Fetch Request
res = http.request(req)
puts "Response HTTP Status Code: #{res.code}"
puts "Response HTTP Response Body: #{res.body}"
rescue StandardError => e
puts "HTTP Request failed (#{e.message})"
end
3. 上传文件到 COS 的 API
在第二步的 API 请求成功后,你需要构建一个请求,来上传文件。这部分需要确保你的各项参数是正确的。
这里我给出一个使用 Jquery 上传的示例,你可以对照我的代码,看一下你自己的代码应该是什么样的。
// 上传文件 (POST https://cos.ap-shanghai.myqcloud.com/7263-rcn-1258788140/testfile)
var formData = new FormData();
formData.append("file", "123");
formData.append("x-cos-meta-fileid", "HBPXgrO3M5Wijh6eLuVVX+iG11rk4mNdQum5Lg10PFCDuk7sQN12Y4t0fG36qkajY6iZGe3GSIo/5ykMG4hdsu1HUJ5OZccS7VA4961UZiJ27pOrXRBtgxYjssuMW52+pyXLIO0sYHvHCQn8EZE=");
formData.append("x-cos-security-token", "oKPjfeWGvRFzSR45azxJoZEzcMozJOWecd700261215792a61eefe56427ac91f6OlXUai4_iST1mbzYo8ph_GCgGejJNvtA1V483_SpzpnsPLeQc43b1MKj3yI5Dr0zT-jfYFB33-fe52ZMdZhEl3dCuJN7buFKPOAQqwEjFlr7gSyOrP5ox350qslAnjKHxORAQVNMR3PwiA1uxMe3tjtOjQKTF-xu1kxTowczdtwPYYC7F-IqbQFZ9q_yIQGNzIKs_-67tIeLl0Zv7iUkCE3KcmJUG9isgjpnCe_BSUsgw6EvBmrYU7eP-AIPuFPJZyC7Ocum11PGr3H4HU2QuZYp1AOWI48izl2wSJyu3CZZGxjsZ2CNHomNw7KvGKvR3OISx74Zzr41mZc7P6RNYPzK6jeE3K3rwWuolKtaqnlPiUQLd9i_9HScv2xBbgD4MHwGZB6jgb3DgYlenCtFlQ");
formData.append("Signature", "q-sign-algorithm=sha1&q-ak=AKIDtxMKuQ9CIgWF-aSrFKfNzPpijPhLSYQ8q-fsI2KfFqA104Sba16xKmbT6RgYpHD-&q-sign-time=1581727591;1581728491&q-key-time=1581727591;1581728491&q-header-list=&q-url-param-list=&q-signature=62f0d5f90dec5153a59b28820f77255aa9baa37e");
formData.append("key", "testfile");
jQuery.ajax({
url: "https://cos.ap-shanghai.myqcloud.com/7263-rcn-1258788140/testfile",
type: "POST",
headers: {
"Content-Type": "multipart/form-data; charset=utf-8; boundary=__X_PAW_BOUNDARY__",
},
processData: false,
contentType: false,
data: formData,
})
.done(function(data, textStatus, jqXHR) {
console.log("HTTP Request Succeeded: " + jqXHR.status);
console.log(data);
})
.fail(function(jqXHR, textStatus, errorThrown) {
console.log("HTTP Request Failed");
})
.always(function() {
/* ... */
});
请求成功后,你会获得一个 HTTP Status Code 为 204 的 Response ,则说明你上传成功了。
总结
最后,我们来进行总结,想要使用云开发的 HTTP API,你需要先请求 Access Token 接口,获取 Token ,并基于此,获取 COS 上传接口。最后,在前端构建 FormData ,上传文件到真正的 COS 中去。最后,当你获得一个 204 的返回码时,就说明文件上传成功了。
扫描下方二维码,关注我的微信公众号,获取每日微信开发知识
或添加我的个人微信:huanchengbai,和我取得联系
大师,您上面的教程清晰明了。
可否请教一下,您说的“最后,在前端构建 FormData ,上传文件到真正的 COS 中去“,但从前端提交,是不是jquery跨域的问题。这一点我好象过不去,可否指教一二,万分感谢!
你好,问下,可以一次传多个文件吗?