COS是腾讯云的一项服务,免费50G存储空间,按外网流量使用情况收费,内网调用免流量。
本文主要讲如何能享受到COS的内网流量,前提当然是你已经有一个ECS服务器了。

一、COS开通&配置

1、开通对象存储服务,比较简单,根据提示开通即可

2、创建Bucket,注意所属地域要与服务器的一致,否则不算内网

3、获取秘钥配置

二、选用wp的COS插件,上传图片时可以同步到COS上

本文采用来自 水冷眸 的cos-sync,插件地址于 下载地址 ,大家可以去下载后直接解压即可,秘钥配置在此插件上会用得上。

当然这个插件存在一些问题,我也稍作修改了一点东西,但由于改动不大且最终效果不好,就不将修改的版本贴出。

至此已经可以使用cos,并且能访问cos的资源;但是此时还不能达到内网流量的目的,如果cos没有使用cdn加速,则流量会耗得很快。

三、如何享受COS内网流量

方法A.

自己实现一个在服务器上读取cos图片的服务,读取完后再返回图片内容;如此页面上直接用img标签即可显示。

评价:实现倒不复杂,只是会遇到点问题,cos上的keep-alive值得注意,设超时时间可解决但不完美。

示例

<?php
  
if(empty($_GET["file"])) {
        die('no access');
}
  
require( dirname( __FILE__ ) . '/../../../wp-blog-header.php' );
require_once('sdk/include.php');
use Qcloudcos\Auth;
use Qcloudcos\Cosapi;
  
Cosapi::setTimeout(180);
// 设置COS所在的区域:
$cos_opt = get_option('cos_options', TRUE);
$regional = esc_attr($cos_opt['regional']);
Cosapi::setRegion($regional);
  
  
//去COS读取文件咯
$file = $_GET["file"];
$extention = pathinfo($file, PATHINFO_EXTENSION);
function getContentType($extention){
    switch ($extention) {
     case 'tif':
     case 'tiff':
      return 'image/tiff'; break;
     case 'fax':
      return 'image/fax'; break;
case 'gif':
      return 'image/gif'; break;
     case 'ico':
      return 'image/x-icon'; break;
     case 'jpe':
     case 'jpeg':
     case 'jpg':
     case 'jfif':
      return 'image/jpeg'; break;
     case 'net':
      return 'image/pnetvue'; break;
     case 'png':
      return 'image/png'; break;
     case 'rp':
      return 'image/vnd.rn-realpix'; break;
     case 'wbmp':
      return 'image/vnd.wap.wbmp'; break;
     case 'bmp':
      return 'application/x-bmp'; break;
     default:
      die('not support type.');
      break;
    }
}
$content_type = getContentType($extention);
  
//获取WP配置信息
$cos_options = get_option('cos_options', TRUE);
$cos_bucket = esc_attr($cos_options['bucket']);
try {
    $ret = Cosapi::stat($cos_bucket, $file);
} catch (Exception $ex) {
    var_dump($ex);
}
  
if(!empty($ret['data']['source_url'])) {
$opts = array(
'http'=>array(
//'protocol_version'=>1.0,
'method'=>"GET",
'timeout'=>1,
)
);
$context = stream_context_create($opts);
$fileres = file_get_contents($ret['data']['source_url'],false,$context);
  
header('Content-type: '.$content_type);
echo $fileres;
}
die('no file');

方法B.

用nginx对cos做一层代理,对外域名是服务器的地址,实际上是服务器读取cos后返回的结果。

评价:实现简单,响应及时。

实现

location ^~ /static/ { 
        rewrite ^/static/(.*) /$1 break; 
        proxy_pass http://你的COS域名.myqcloud.com/; 
    }

访问: http://你的博客域名/static/存储路径

四、cos-sync插件的建议不勾选?

问:能否不在本地保存,能否不上传缩略图?
答:可以,但会有一些问题(本人尝试改了一些后,功能基本不受影响,但体验差了些)。

问题A.

不勾选后,媒体库的缩略图出不来。

原因:服务器不存储,无法得知图片size,导致默认成了1的宽高

解决

1.wp-includes/media.php 莫约444行改为如下

// Very small dimensions may result in 0, 1 should be the minimum.
$w = max ( 150, (int) round( $current_width  * $ratio ) );
$h = max ( 150, (int) round( $current_height * $ratio ) );

2.wp-admin/includes/image-edit.php 莫约606行改为如下

$w2 = max ( 150, $w * $ratio );
$h2 = max ( 150, $h * $ratio );

问题B.

写文章或页面时,插入媒体库的图片后,预览看不到图片。

原因:服务器不存储,无法得知图片size,导致默认成了1的宽高

解决

1.修改wp-includes/media_template.php 莫约680行:

<# if ( 'undefined' !== typeof data.sizes ) { #>
<label class="setting">
<span><?php _e('Size'); ?></span>
<select class="size" name="size"
data-setting="size"
<# if ( data.userSettings ) { #>
data-user-setting="imgsize"
<# } #>>
<?php
/** This filter is documented in wp-admin/includes/media.php */
$sizes = apply_filters( 'image_size_names_choose', array(
'thumbnail' => __('Thumbnail'),
'medium'    => __('Medium'),
'large'     => __('Large'),
'full'      => __('Full Size'),
) );
  
foreach ( $sizes as $value => $name ) : ?>
<#
var size = data.sizes['<?php echo esc_js( $value ); ?>'];
if ( size ) { #>
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, 'full' ); ?>>
<?php echo esc_html( $name ); ?> –  × 
</option>
<# } #>
<?php endforeach; ?>
</select>
</label>
        <# } else { #>
            <label class="setting">
                <input type="hidden" name="size" value="full" />
            </label>
<# } #>

2.莫约931行开始:

<# if ( 'undefined' !== typeof data.attachment.sizes ) { #>
<label class="setting size">
<span><?php _e('Size'); ?></span>
<select class="size" name="size"
data-setting="size"
<# if ( data.userSettings ) { #>
data-user-setting="imgsize"
<# } #>>
<?php
/** This filter is documented in wp-admin/includes/media.php */
$sizes = apply_filters( 'image_size_names_choose', array(
'thumbnail' => __('Thumbnail'),
'medium'    => __('Medium'),
'large'     => __('Large'),
'full'      => __('Full Size'),
) );
  
foreach ( $sizes as $value => $name ) : ?>
<#
var size = data.sizes['<?php echo esc_js( $value ); ?>'];
if ( size ) { #>
<option value="<?php echo esc_attr( $value ); ?>">
<?php echo esc_html( $name ); ?> –  × 
</option>
<# } #>
<?php endforeach; ?>
<option value="<?php echo esc_attr( 'custom' ); ?>">
<?php _e( 'Custom Size' ); ?>
</option>
</select>
</label>
<# } else { #>
                            <label class="setting size">
                                <input type="hidden" name="size" value="full" />
</label>
                        <# } #>