使用BOS存储静态资源

为了保持代码轻量,我们建议您将静态资源存储到BOS。BOS提供控制台、API、SDK三种方式方便您灵活地进行操作,控制台方式请参见上传Object,这里我们分别介绍如何在Node.js、PHP、Python、Java环境中使用API/SDK存储静态资源。

Node.js

由于BOS暂不提供Node.js SDK,Node.js环境目前只能通过基于签名的API访问BOS。代码示例如下:

  • settings.js

    module.exports = exports = {
        bos: {
            expire: 1800,
            ak: '<AK>',
            sk: '<SK>'
        }
    };
    
  • index.js

    var BOS = require('./BOS');
    var http = require('http');
    var bucket = '<Bucket_Name>';  //请选用一个唯一的bucket名称,否则create_bucket会因为重名报错
    var key = 'sampleKey.txt';
    var port = 18080;
    
    //创建 bucket
    BOS.putBucket(bucket, function(err, data) {
        if(!err) {
            console.log("create bucket success");
        }
    })
    
    http.createServer(function(request, res) {
        //上传内容到BOS
        BOS.putObject(bucket, key, 'Hello World', function (err, data) {
            if (!err) {
                console.log('upload success');
                // 从BOS下载内容
                BOS.getObject(bucket, key, null, function (err, data) {
                    if (!err) {
                        console.log('download success with ' + data);
                        res.end(data);
                    }
                });
            }
    
        })
    }).listen(port);
    
  • BOSRequest.js

    var crypto = require('crypto');
    var fs = require('fs');
    var http = require('http');
    var settings = require('./settings');
    
    module.exports = function BOSRequest(method, bucket, object, params, customHeaders, expire, data, callback) {
      bucket = bucket || '';
      object = object || '';
      params = params || {};
      callback = callback || console.log;
      var accessKeyId = settings.bos.ak;
      var secretAccessKey = settings.bos.sk;
      var requestDate = new Date().toISOString().slice(0, -5) + 'Z';
    
      var httpMethod = method;
      var path = ['/v1', bucket, normalize(object, true)].join('/');
      var headersToSign = [];
      var headers = {
        'host': 'bj.bcebos.com',
        'x-bce-date': requestDate
      };
      if(customHeaders != null) {
        for(var key in customHeaders) {
          headersToSign.push(key);
          headers[key] = customHeaders[key];
        }
      }
      if(data != null) {
        data = new Buffer(data);
        headers['Content-Type'] = 'application/octet-stream';
        headers['Content-Length'] = data.length;
      }
      var content = 'bce-auth-v1/'+ accessKeyId +'/'+ requestDate +'/' + expire;
      var SigningKey = crypto.createHmac('sha256', secretAccessKey).update(content).digest('hex');
      var CanonicalURI = path;
      var CanonicalQueryString = getCanonicalQueryString(params);
      var CanonicalHeaders = getCanonicalHeaders(headers);
      var CanonicalRequest = [httpMethod.toUpperCase(), CanonicalURI, CanonicalQueryString, CanonicalHeaders].join('\n');
      var Signature = crypto.createHmac('sha256', SigningKey).update(CanonicalRequest).digest('hex');
      headers.Authorization = [content, headersToSign.join(';'), Signature].join('/');
    
      var options = {
        host: headers.host,
        path: path+'?'+getCanonicalQueryString(params),
        method: httpMethod,
        headers: headers
      };
      var req = http.request(options, function (res) {
        var data = '';
        res.on('data', function (chunk) {
          data += chunk;
        }).on('end', function () {
          try {
            data = eval('('+ data +')');
          } catch(e) {
          } finally {
            if(res.statusCode >= 300) {
              callback(new Error(data.code), null);
            } else {
              callback(null, data);
            }
          }
        }).on('error', function (err) {
          console.log(err);
          callback(err, null);
        })
      });
      req.end(data);
    
      function getCanonicalQueryString(params) {
        var result = [];
        for(var key in params) {
          if(key.toLowerCase() != 'authorization') {
            result.push(normalize(key) + '=' + normalize(params[key]));
          }
        }
        result.sort();
        return result.join('&');
      }
    
      function getCanonicalHeaders(headers) {
        headersToSign = ['host', 'content-md5', 'content-length', 'content-type'].concat(headersToSign);
        var result = [];
        var tempHeaderToSign = [];
        for(var key in headers) {
          var keyLower = key.toLowerCase();
          var value = headers[key].toString().trim();
          if(/^x-bce-/.test(keyLower) || new RegExp(keyLower).test(headersToSign)) {
            var temp = normalize(keyLower) + ':' + normalize(value);
            tempHeaderToSign.push(normalize(keyLower));
            result.push(temp);
          }
        }
        headersToSign = tempHeaderToSign.sort();
        result.sort();
        return result.join('\n');
      }
    
      function normalize(input, exceptSlash) {
        var result = '';
        if(input == null) {
          return result;
        }
        input = input.toString();
        for (var i = 0; i < input.length; i++) {
          var ch = input.charAt(i);
          if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '-' || ch == '~' || ch == '.') {
            result += ch;
          } else if (ch == '/') {
            result += !exceptSlash ? '%2F' : ch;
          } else {
            result += '%' + new Buffer(ch).toString('hex').toUpperCase();
          }
        }
        return result;
      }
    };
    
  • BOS.js

    var BOSRequest = require('./BOSRequest');
    var settings = require('./settings');;
    
    module.exports = BOS = {
      listBuckets: function (cb) {
        BOSRequest('GET', null, null, null, null, settings.bos.expire, null, cb);
      },
      putBucket: function (bucket, cb) {
        BOSRequest('PUT', bucket, null, null, null, settings.bos.expire, null, cb);
      },
      deleteBucket: function (bucket, cb) {
        BOSRequest('DELETE', bucket, null, null, null, settings.bos.expire, null, cb);
      },
      listObjects: function (bucket, prefix, marker, maxKeys, cb) {
        BOSRequest('GET', bucket, null, {
          prefix: prefix,
          marker: marker,
          maxKeys: maxKeys
        }, null, settings.bos.expire, null, cb);
      },
      putObject: function (bucket, object, data, cb) {
        BOSRequest('PUT', bucket, object, null, null, settings.bos.expire, data, cb);
      },
      deleteObject: function (bucket, object, cb) {
        BOSRequest('DELETE', bucket, object, null, null, settings.bos.expire, null, cb);
      },
      getObject: function (bucket, object, range, cb) {
        BOSRequest('GET', bucket, object, null, !range?null:{
          range: 'bytes='+range
        }, settings.bos.expire, null, cb);
      }
    };
    

PHP

  1. 下载BOS PHP SDK并解压。
  2. 将解压包中的BaiduBce.phar复制到PHP项目的根目录下,并在根目录下添加下述示例代码:

    <?php
    
    include 'BaiduBce.phar';
    use BaiduBce\Util\Time;
    use BaiduBce\Services\Bos\BosClient;
    date_default_timezone_set("Asia/Shanghai");
    
    $BOS_TEST_CONFIG =
        array(
            'credentials' => array(
                'ak' => '<AK>',
                'sk' => '<SK>',
            ),
            'endpoint' => 'http://bj.bcebos.com',   //BOS HOST
        );
    
    $bucketName = '<Bucket_Name>'; //请选用一个唯一的 bucket名称,否则create_bucket会因为重名报错
    
    $targetKey = 'sampleKey.txt';
    
    $client = new BosClient($BOS_TEST_CONFIG);
    //新建一个bucket
    $client->createBucket($bucketName);
    
    //上传内容到BOS
    $client->putObjectFromString($bucketName, $targetKey, "hello world");
    
    //从BOS下载内容
    $content = $client->getObjectAsString($bucketName, $targetKey);
    print_r("Content from BOS:" . $content);
    
    ?>
    

Python

  1. 下载BOS Python SDK并解压。
  2. 将解压包中的baidubce目录复制到python项目的根目录下,并在根目录下添加下述示例代码:

    #-*- coding:utf-8 -*-
    
    import string
    from baidubce.services.bos.bos_client import BosClient
    from baidubce.bce_client_configuration import BceClientConfiguration
    from baidubce.auth.bce_credentials import BceCredentials
    
    def test_bos():
        HOST = 'bj.bcebos.com'
        AK = '<AK>'
        SK = '<SK>'
        bucket_name = '<Bucket_Name>' # 请选用一个唯一的bucket名称,否则create_bucket会因为重名报错
        target_key = 'sampleKey.txt'
    
        # 创建BOS client
        bos_client = BosClient(BceClientConfiguration(credentials=BceCredentials(AK, SK), endpoint=HOST))
        # 创建一个bucket
        bos_client.create_bucket(bucket_name)
        # 上传内容到BOS
        bos_client.put_object_from_string(bucket_name, target_key, "hello world")
        # 从BOS下载文件写入字符串
        content = bos_client.get_object_as_string(bucket_name, target_key)
        return content
    
    def app(environ, start_response):
        status = '200 OK'
        headers = [('Content-type', 'text/html')]
        start_response(status, headers)
        try:
            return test_bos()
        except Exception as e:
            return "exception"
    
    from bae.core.wsgi import WSGIApplication
    application = WSGIApplication(app)
    

Java

  1. 下载BOS Java SDK并解压。
  2. 将解压包中lib目录下的bce-java-sdk-{version}.jar及third-party目录下的所有*.jar引入java项目。代码示例如下:

    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import com.baidubce.services.bos.BosClient;
    import com.baidubce.services.bos.BosClientConfiguration;
    import com.baidubce.auth.DefaultBceCredentials;
    import com.baidubce.services.bos.model.PutObjectResponse;
    import com.baidubce.services.bos.model.BosObject;
    import java.io.InputStream;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.ByteArrayInputStream;
    import java.io.PrintWriter;
    
    public class BosTest extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
            try {
                String ACCESS_KEY_ID = "<AK>";   
                String SECRET_ACCESS_KEY = "<SK>";
                String bucketName = "<Bucket_Name>"; //请选用一个唯一的 bucket名称,否则create_bucket会因为重名报错
                String targetKey = "sampleKey.txt"; 
    
                //创建BOS client
                BosClientConfiguration config = new BosClientConfiguration();
                config.setCredentials(new DefaultBceCredentials(ACCESS_KEY_ID, SECRET_ACCESS_KEY));
                BosClient client = new BosClient(config);
    
                //创建bucket
                client.createBucket(bucketName);
    
                //上传内容到BOS
                InputStream inputStream = new ByteArrayInputStream("hello world".getBytes());;
                PutObjectResponse putObjectResponseFromInputStream = client.putObject(bucketName, targetKey, inputStream);
                System.out.println(putObjectResponseFromInputStream.getETag());
    
                //从BOS中下载内容
                BosObject object = client.getObject(bucketName, targetKey);
                InputStream objectContent = object.getObjectContent();
                BufferedReader in = new BufferedReader(new InputStreamReader(objectContent));
                String line = "";
                PrintWriter out = resp.getWriter();
                while ((line = in.readLine()) != null){
                    out.print(line);
                }
    
            } catch (Exception e) {
                e.printStackTrace(resp.getWriter());
            }
        }
    }