xiebruce

xiebruce 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑

php开发者

个人动态

xiebruce 发布了文章 · 6月2日

PHP分片上传文件到又拍云对象存储

本文参加又拍云原创技术征文活动

注册&实名认证

注册我就不说了,大家自行前往又拍云注册就行。

注册之后需要实名认证,否则无法使用,但由于我已经实名认证了(当时没截图),网上也很难找到截图,我找了一张很模糊的,不过还是能看清的

认证方式:支付宝芝麻信用有700分以上选支付宝芝麻信用认证,没有的话选人工(选人工应该要上传手持身份证的照片)
所属行业:我的是博客,所以我选的是门户网站→博客
网站/产品:就填你的网站名称(暂时没有就随便想一个)
网站地址:写你自己搭建的博客域名,没有的话用csdn,博客园,新浪博客之类的博客地址,再没有的话好像也可以不写
个人名称:写你的姓名(跟身份证要一样)
身份证号码:如实填写,否则无法通过实名认证

创建存储桶

登录后,点击页面右上角的控制台,然后选择云产品→云存储
Xnip2020-06-02_13-02-15.jpg

点击右上角创建一个服务(在这里叫服务,其它云一般叫“存储桶”,英文“bucket”)
-w1179

按下图填写,其中加速按你的需求,但如果选择全球加速,价格肯定比国内加速贵;操作员如果你之前没有就需要新建并授权,因为调用api需要一个账号密码,但这个账号密码并不是你注册又拍云的那个账号密码,而是要在这里新建一个,叫“操作员”

测试操作员账号及默认域名

又拍云的对象存储是支持直接使用ftp登录的,这里我使用filezilla登录(其它ftp工具也类似)。

打开filezilla,如下图所示,点击左上角的“Site Manager”图标(也可直接点击菜单FileSite Manager)进入以下界面,然后按下图填写参数

如果ftp能连接上,也能上传文件,说明操作员账号没啥问题,连不上可能是前面忘了授权,可以点击右上角用户名→账户管理
-w461

然后点击操作员→管理,查看是否已经给了这个操作员权限,如果没有给,则给它加上权限,然后再试,应该就没问题了
-w1199

另外,我们还可以在网页上上传文件
-w1174

创建一个服务后,又拍云默认会给我们一个测试域名,域名结构为”https://服务名.test.upcdn.net“,其实也可以在控制台中看到,点击上图中的“配置”→选择域名管理选项卡(实际上默认就是该选项卡)→滚动到最底下即可看见送的测试域名。

使用php分片上传文件

REST API文档,其中并行式断点续传和串行式断点续传,就是分片上传了
-w1016

不过又拍云有写好的php-sdk,就不用我们自己写这个,直接传参就行。

创建一个文件夹UploadToUpyun,在终端中进入该文件夹,使用composer安装sdk(没有composer命令请自行安装,都0202年了应该都有吧?)

composer require upyun/sdk

安装完成后,在UploadToUpyun文件夹中创建一个index.php,代码如下,注释已经写的非常清楚,填上你的参数即可正常运行,相信没有人不会

<?php
require 'vendor/autoload.php';

use Upyun\Config;
use Upyun\Upyun;

//你自己创建的服务的名称
$serviceName = 'YOUR_SERVICE_NAME';
//操作员账号
$operator = 'YOUR_OPERATOR_NAME';
//操作员密码
$password = 'YOUR_OPERATOR_PASSWORD';
//要上传到哪个目录下
$directory = '/UploadToUpyun/test/';
//要上传的文件的绝对路径(请换成你电脑上一个图片文件的路径)
$uploadFilePath = '/Users/bruce/Downloads/Ts8CYigv.png';
//上传文件名,为什么上传文件名要叫key而不叫filename呢?因为对象存储其实就是一个key value
//的存储结构,你可以认为它就是个redis,key就是redis键名,value就是这个key对应的内容。
$key = basename($uploadFilePath);
//又拍云默认域名在:云存储→选择一个服务并点配置→配置的第一项默认就是域名管理→滚动到最后就能看到默认域名
$defaultDomain = 'http://' . $serviceName . '.test.upcdn.net';

//在对象存储中,其实并没有实际意义上的"目录"(或者叫"文件夹"),整个文件夹和最后的key一起,组成的一个整体也是key
//举例:我要把文件存到"2020/06/02/test.jpg",那么这整个就是一个key,而内容当然就是test.jpg这张图片的二进制数据了。
if($directory){
    //真正使用时,$directory可能是用户传过来的,在不知道用户是否写了右斜杠的情况下,统一先去掉再添加一个
    $key = rtrim($directory, '/') . '/' . $key;
}

//使用又拍云php-sdk上传文件非常方便,很new一个config对象
$serviceConfig = new Config($serviceName, $operator, $password);
// 15728640 = 15M,如果文件大于15M,则使用并行分块上传
if(filesize($uploadFilePath) > 15728640){
    /* uploadType有两个值
       - BLOCK : 串行分块上传
       - BLOCK_PARALLEL : 并行分块上传
    */
    //然后可对new出的config对象的属性继续设置参数(有哪些参数可直接查看Config类: vendor/upyun/sdk/src/Upyun/Config.php)
    //设置uploadType=BLOCK_PARALLEL表示使用并行分片上传
    $serviceConfig->uploadType = 'BLOCK_PARALLEL';
}
$client = new Upyun($serviceConfig);
$fp = fopen($uploadFilePath, 'rb');
$retArr = $client->write($key, $fp);
// var_dump($retArr);exit;

/*
 * 返回的$retArr的值
 * array(6) {
      'x-upyun-content-length' =>
      string(5) "47028"
      'x-upyun-height' =>
      string(3) "473"
      'x-upyun-content-type' =>
      string(9) "image/png"
      'x-upyun-file-type' =>
      string(3) "PNG"
      'x-upyun-width' =>
      string(3) "839"
      'x-upyun-frames' =>
      string(1) "1"
    }
 */

//我们随便拿一个元素来判断是否上传成功
if(isset($retArr['x-upyun-content-length'])){
    //在实际使用中,$key可能是用户传过来的,在不知道$key是否以斜杠开头的情况下,统一先去掉再自己添加一个
    echo $defaultDomain . '/' . ltrim($key);
}else{
    echo 'Upload failed.';
}

好了,到这里就写完了,enjoy!

查看原文

赞 0 收藏 0 评论 0

xiebruce 回答了问题 · 2019-10-21

解决git add 多个文件,但想忽略某一个文件

先用以下命令添加所有

git add -u

再以下命令排除掉你不想添加进去的某几个文件,比如我这里要排除“static/js/dashboard.js”文件(这个路径可以用git status查看):

git reset -- static/js/dashboard.js

关注 6 回答 5

xiebruce 回答了问题 · 2019-09-08

php-cli能获取系统剪贴板中的图片吗?

一段时间过去了,也没人知道,我自己研究出来并且还写了个插件:php-get-image-from-clipboard,兼容macOS、Windows、Linux三大平台。

原理:

  • macOS是通过使用php调用pngpaste命令来生成的,需要安装pngpastebrew install pngpaste
  • Windows是通过使用php调用Powershell来生成的,Win10什么都不用动,Win7要升级Powershell到5.1;
  • Linix是通过使用php调试xclip来生成截图的,Ubuntu的话,使用apt install xclip来安装xclip

关注 3 回答 3

xiebruce 提出了问题 · 2019-06-21

用link标签无法实现http2的server push

服务器已经配置好:

server {
    # listen在原https配置文件基础上添加http2
    listen 443 ssl http2;
    # 添加一句http2_push_preload on表示开启server push功能
    http2_push_preload on;
    ……
}

并且用以下的方式(php)也成功了:

<?php
    header("link: </styles.css>; rel=preload; as=style", false);
    header("link: </script.js>; rel=preload; as=script", false);

但是据说还可以用link标签的方式来指定要推送的资源:

<link rel="preload" href="/styles.css" as="style">
<link rel="preload" href="/script.js" as="script">

但我一直没试成功这种方式,有人知道这是什么问题吗?

关注 2 回答 1

xiebruce 评论了文章 · 2019-04-26

七牛云图床上传工具-iUploader

软件介绍:
iUploader主要功能将图片上传至七牛云,返回 Markdown 格式的链接到剪贴板

功能介绍:

  1. 图片本地压缩
  2. 图片右键上传
  3. 图片复制上传
  4. 图片拖拽上传
  5. https加密上传

开发:
继承七牛云SDK,使用swift开发,App自签上传凭证,自动选择存储区域,通过https加密上传。


联系方式:

邮箱:iChochy@qq.com
网站:https://iuploader.ichochy.com

注: 处女作
Cloud

查看原文

xiebruce 评论了文章 · 2019-04-26

分享一个自己写的开源图床ImgURL

ImgURL是一款使用PHP + SQLite 3开发的图床程序,免费开源,支持图像裁剪、压缩、自动鉴黄识别等多种功能,部署简单,管理方便。

目前已经实现的功能

  • 支持拽拖上传、多图上传、Ctrl + V粘贴上传、URL上传
  • 支持图片裁剪,自动生成缩略图
  • 限制访客上传数量
  • 图片压缩/批量压缩
  • 图片鉴黄/批量鉴黄
  • API支持

DEMO

安装ImgURL

其它说明

查看原文

xiebruce 评论了文章 · 2019-04-26

我的最佳写作方式

最佳喜欢上了写作,喜欢自己写的东西能被别人阅读,赞赏,也希望我写的东西能更有价值,体验也更好。

今天我分享的是我的最佳写作方式。

我的最佳写作方式

工具汇总

markdown编辑器截图工具gif录制工具图床工具
TyporaQQ / wechatlicecapiPic

markdown编辑器 · Typora

完全免费的markdown编辑器,无与伦比的写作体验,让人爱不释手,具体的特性请移步官网:https://typora.io/

我最常用的快捷键是Command+/,可以切换源码模式和打字机模式。

typora

图传工具iPic

仅仅有好的编辑器还不够,还需要图床工具将你的图片自动上传到云端,最好是能够结合你使用的markdown编辑器一起使用,最好是截图后直接粘贴,然后上传。

那么iPic是首选,因为Typora内置了iPic的功能,如下图:

ipic

iPic支持很多种图传工具,我现在用的是腾讯COS,这个工具默认是免费的,但是默认只支持免费的新浪微博图传,如果你要使用其他图传就要收费了,年费50元。

iPic的作者是全职独立开发者Jason,已经写了很多类似的mac工具,都很优秀,官网:https://toolinbox.net/

截图工具

QQ和微信截图应该是大家都在用的,非常方便,截图后可以粘贴到任何地方,QQ还支持视频录制功能。

gif录制工具

这里我就要介绍强大的LICEcap了,用来做屏幕截图的,录制出来的gif很小,我的所有gif都是通过它来制作的。

详细请移步官网:https://www.cockos.com/licecap/

查看原文

xiebruce 评论了文章 · 2019-04-26

SpringBoot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床

Github 地址:https://github.com/Snailclimb/springboot-integration-examples(SpringBoot和其他常用技术的整合,可能是你遇到的讲解最详细的学习案例,力争新手也能看懂并且能够在看完之后独立实践。基于最新的 SpringBoot2.0+,是你学习SpringBoot 的最佳指南。) ,欢迎各位 Star。

笔主很早就开始用阿里云OSS 存储服务当做自己的图床了。如果没有用过阿里云OSS 存储服务或者不是很了解这个东西的可以看看官方文档,我这里就不多做介绍了。阿里云对象存储 OSS文档,:

https://help.aliyun.com/product/31815.html?spm=a2c4g.11186623.6.540.4e401c62EyJK5T

本篇文章会介绍到 SpringBoot 整合阿里云OSS 存储服务实现文件上传下载以及简单的查看。其实今天将的应该算的上是一个简单的小案例了,涉及到的知识点还算是比较多。

一 开发前的准备

1.1 前置知识

具有 Java 基础以及SpringBoot 简单基础知识即可。

1.2 环境参数

  • 开发工具:IDEA
  • 基础工具:Maven+JDK8
  • 所用技术:SpringBoot+阿里云OSS 存储服务 Java 相关API
  • SpringBoot版本:2.1.0

1.3 你能学到什么

  • SpringBoot 整合 阿里云OSS 存储服务并编写相关工具类
  • SpringBoot 整合 thymeleaf 并实现前后端传值
  • SpringBoot 从配置文件读取值并注入到类中
  • 如何自己搭建一个图床使用(通过前端选择图片,支持预览,但不支持修改图片)

1.4 创建工程

创建一个基本的 SpringBoot 项目,我这里就不多说这方面问题了,具体可以参考下面这篇文章:

https://blog.csdn.net/qq_3433...

1.5 项目结构

项目结构

1.6 配置 pom 文件中的相关依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- 阿里云OSS-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

二 配置阿里云 OSS 存储相关属性

我在项目中使用的通过常量类来配置,不过你也可以使用 .properties 配置文件来配置,然后@ConfigurationProperties 注解注入到类中。

2.1 通过常量类配置(本项目使用的方式)

AliyunOSSConfigConstant.java

/**
 * @Auther: SnailClimb
 * @Date: 2018/12/4 15:09
 * @Description: 阿里云OSS存储的相关常量配置.我这里通过常量类来配置的,当然你也可以通过.properties 配置文件来配置,
 * 然后利用 SpringBoot 的@ConfigurationProperties 注解来注入
 */
public class AliyunOSSConfigConstant {
    //私有构造方法 禁止该类初始化
    private AliyunOSSConfigConstant() {
    }

    //仓库名称
    public static final String BUCKE_NAME = "my-blog-to-use";
    //地域节点
    public static final String END_POINT = "oss-cn-beijing.aliyuncs.com";
    //AccessKey ID
    public static final String AccessKey_ID = "你的AccessKeyID";
    //Access Key Secret
    public static final String AccessKey_Secret = "你的AccessKeySecret";
    //仓库中的某个文件夹
    public static final String FILE_HOST = "test";
}

到阿里云 OSS 控制台:https://oss.console.aliyun.com/overview获取上述相关信息:

获取 BUCKE_NAME 和 END_POINT:

获取BUCKE_NAME和END_POINT

获取AccessKey ID和Access Key Secret第一步:

获取AccessKey ID和Access Key Secret第一步

获取AccessKey ID和Access Key Secret第二步:

获取AccessKey ID和Access Key Secret第二步

2.2 通过.properties 配置

#OSS配置
aliyun.oss.bucketname=my-blog-to-use
aliyun.oss.endpoint=oss-cn-beijing.aliyuncs.com
#阿里云主账号AccessKey拥有所有API的访问权限,风险很高。建议创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
aliyun.oss.keyid=你的AccessKeyID
aliyun.oss.keysecret=你的AccessKeySecret
aliyun.oss.filehost=test

然后新建一个类将属性注入:

@Component
@PropertySource(value = "classpath:application-oss.properties")
@ConfigurationProperties(prefix = "aliyun.oss")
/**
 * 阿里云oss的配置类
 */
public class AliyunOSSConfig {
    private String bucketname;
    private String endpoint;
    private String keyid;
    private String keysecret;
    private String filehost;
    ...
    此处省略getter、setter以及 toString方法
}    

三 工具类相关方法编写

该工具类主要提供了三个方法:上传文件 upLoad(File file) 、通过文件名下载文件downloadFile(String objectName, String localFileName) 、列出某个文件夹下的所有文件listFile( )。笔主比较懒,代码可能还比较简陋,各位可以懂懂自己的脑子,参考阿里云官方提供的相关文档来根据自己的需求来优化。Java API文档地址如下:

https://help.aliyun.com/document_detail/32008.html?spm=a2c4g.11186623.6.703.238374b4PsMzWf

/**
 * @Author: SnailClimb
 * @Date: 2018/12/1 16:56
 * @Description: 阿里云OSS服务相关工具类.
 * Java API文档地址:https://help.aliyun.com/document_detail/32008.html?spm=a2c4g.11186623.6.703.238374b4PsMzWf
 */
@Component
public class AliyunOSSUtil {
    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(AliyunOSSUtil.class);
    private static String FILE_URL;
    private static String bucketName = AliyunOSSConfigConstant.BUCKE_NAME;
    private static String endpoint = AliyunOSSConfigConstant.END_POINT;
    private static String accessKeyId = AliyunOSSConfigConstant.AccessKey_ID;
    private static String accessKeySecret = AliyunOSSConfigConstant.AccessKey_Secret;
    private static String fileHost = AliyunOSSConfigConstant.FILE_HOST;


    /**
     * 上传文件。
     *
     * @param file 需要上传的文件路径
     * @return 如果上传的文件是图片的话,会返回图片的"URL",如果非图片的话会返回"非图片,不可预览。文件路径为:+文件路径"
     */
    public static String upLoad(File file) {
        // 默认值为:true
        boolean isImage = true;
        // 判断所要上传的图片是否是图片,图片可以预览,其他文件不提供通过URL预览
        try {
            Image image = ImageIO.read(file);
            isImage = image == null ? false : true;
        } catch (IOException e) {
            e.printStackTrace();
        }

        logger.info("------OSS文件上传开始--------" + file.getName());

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = format.format(new Date());

        // 判断文件
        if (file == null) {
            return null;
        }
        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            // 判断容器是否存在,不存在就创建
            if (!ossClient.doesBucketExist(bucketName)) {
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
            // 设置文件路径和名称
            String fileUrl = fileHost + "/" + (dateStr + "/" + UUID.randomUUID().toString().replace("-", "") + "-" + file.getName());
            if (isImage) {//如果是图片,则图片的URL为:....
                FILE_URL = "https://" + bucketName + "." + endpoint + "/" + fileUrl;
            } else {
                FILE_URL = "非图片,不可预览。文件路径为:" + fileUrl;
            }

            // 上传文件
            PutObjectResult result = ossClient.putObject(new PutObjectRequest(bucketName, fileUrl, file));
            // 设置权限(公开读)
            ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
            if (result != null) {
                logger.info("------OSS文件上传成功------" + fileUrl);
            }
        } catch (OSSException oe) {
            logger.error(oe.getMessage());
        } catch (ClientException ce) {
            logger.error(ce.getErrorMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return FILE_URL;
    }


    /**
     * 通过文件名下载文件
     *
     * @param objectName    要下载的文件名
     * @param localFileName 本地要创建的文件名
     */
    public static void downloadFile(String objectName, String localFileName) {

        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。
        ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(localFileName));
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * 列举 test 文件下所有的文件
     */
    public static void listFile() {
        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 构造ListObjectsRequest请求。
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);

        // 设置prefix参数来获取fun目录下的所有文件。
        listObjectsRequest.setPrefix("test/");
        // 列出文件。
        ObjectListing listing = ossClient.listObjects(listObjectsRequest);
        // 遍历所有文件。
        System.out.println("Objects:");
        for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
            System.out.println(objectSummary.getKey());
        }
        // 遍历所有commonPrefix。
        System.out.println("CommonPrefixes:");
        for (String commonPrefix : listing.getCommonPrefixes()) {
            System.out.println(commonPrefix);
        }
        // 关闭OSSClient。
        ossClient.shutdown();
    }
}

四 Controller 层编写相关测试方法

上传文件 upLoad(File file) 、通过文件名下载文件downloadFile(String objectName, String localFileName) 、列出某个文件夹下的所有文件listFile( ) 这三个方法都在下面有对应的简单测试。另外,还有一个方法 uploadPicture(@RequestParam("file") MultipartFile file, Model model)对应于我们等下要实现的图床功能,该方法从前端接受到图片之后上传到阿里云OSS存储空间并返回上传成功的图片 URL 地址给前端。

注意将下面的相关路径改成自己的,不然会报错!!!

/**
 * @Author: SnailClimb
 * @Date: 2018/12/2 16:56
 * @Description: 阿里云OSS服务Controller
 */
@Controller
@RequestMapping("/oss")
public class AliyunOSSController {

    private final org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private AliyunOSSUtil aliyunOSSUtil;

    /**
     * 测试上传文件到阿里云OSS存储
     *
     * @return
     */
    @RequestMapping("/testUpload")
    @ResponseBody
    public String testUpload() {
        File file = new File("E:/Picture/test.jpg");
        AliyunOSSUtil aliyunOSSUtil = new AliyunOSSUtil();
        String url = aliyunOSSUtil.upLoad(file);
        System.out.println(url);
        return "success";
    }
    /**
     * 通过文件名下载文件
     */
    @RequestMapping("/testDownload")
    @ResponseBody
    public String testDownload() {
        AliyunOSSUtil aliyunOSSUtil = new AliyunOSSUtil();
        aliyunOSSUtil.downloadFile(
                "test/2018-12-04/e3f892c27f07462a864a43b8187d4562-rawpixel-600782-unsplash.jpg","E:/Picture/e3f892c27f07462a864a43b8187d4562-rawpixel-600782-unsplash.jpg");
        return "success";
    }
    /**
     * 列出某个文件夹下的所有文件
     */
    @RequestMapping("/testListFile")
    @ResponseBody
    public String testListFile() {
        AliyunOSSUtil aliyunOSSUtil = new AliyunOSSUtil();
        aliyunOSSUtil.listFile();
        return "success";
    }

    /**
     * 文件上传(供前端调用)
     */
    @RequestMapping(value = "/uploadFile")
    public String uploadPicture(@RequestParam("file") MultipartFile file, Model model) {
        logger.info("文件上传");
        String filename = file.getOriginalFilename();
        System.out.println(filename);
        try {

            if (file != null) {
                if (!"".equals(filename.trim())) {
                    File newFile = new File(filename);
                    FileOutputStream os = new FileOutputStream(newFile);
                    os.write(file.getBytes());
                    os.close();
                    file.transferTo(newFile);
                    // 上传到OSS
                    String uploadUrl = aliyunOSSUtil.upLoad(newFile);
                    model.addAttribute("url",uploadUrl);
                }

            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return "success";
    }
}

五 启动类

@SpringBootApplication
public class SpringbootOssApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootOssApplication.class, args);
    }
}

六 上传图片相关前端页面

注意引入jquery ,避免前端出错。

index.html

JS 的内容主要是让我们上传的图片可以预览,就像我们在网站更换头像的时候一样。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>基于阿里云OSS存储的图床</title>
    <script th:data-original="@{/js/jquery-3.3.1.js}"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #submit {
            margin-left: 15px;
        }

        .preview_box img {
            width: 200px;
        }
    </style>
</head>
<body>

<form action="/oss/uploadFile" enctype="multipart/form-data" method="post">
    <div class="form-group" id="group">
        <input type="file" id="img_input" name="file" accept="image/*">
        <label for="img_input" ></label>
    </div>
    <button type="submit" id="submit">上传</button>
    <!--预览图片-->
    <div class="preview_box"></div>
</form>
<script type="text/javascript">

    $("#img_input").on("change", function (e) {
        var file = e.target.files[0]; //获取图片资源
        // 只选择图片文件
        if (!file.type.match('image.*')) {
            return false;
        }
        var reader = new FileReader();
        reader.readAsDataURL(file); // 读取文件
        // 渲染文件
        reader.onload = function (arg) {

            var img = '<img class="preview" data-original="' + arg.target.result + '" alt="preview"/>';
            $(".preview_box").empty().append(img);
        }
    });
</script>
</body>
</html>

success.html

通过 <span th:text="${url}"></span> 引用后端传过来的值。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>上传结果</title>
</head>
<body>
<h1>上传成功!</h1>
图片地址为:<span th:text="${url}"></span>
</body>
</html>

七 测试我们的图床

访问 :http://localhost:8080/

① 上传图片

② 图片上传成功返回图片地址

③ 通过图片 URL 访问图片

通过图片 URL 访问图片

我们终于能够独立利用阿里云 OSS 完成一个自己的图床服务,但是其实如果你想用阿里云OSS当做图床可以直接使用极简图床:http://jiantuku.com 上传图片,比较方便!大家可能心里在想那你特么让我实现个图床干嘛?我觉得通过学习,大家以后可以做很多事情,比如 利用阿里云OSS 存储服务存放自己网站的相关图片。

ThoughtWorks准入职Java工程师。专注Java知识分享!开源 Java 学习指南——JavaGuide(12k+ Star)的作者。公众号多篇文章被各大技术社区转载。公众号后台回复关键字“1”可以领取一份我精选的Java资源哦!

我的公众号

查看原文

xiebruce 提出了问题 · 2019-04-26

php-cli能获取系统剪贴板中的图片吗?

像Python就可以通过用Pillow(PIL)来获取剪贴板中的图片,php脚本纯获取吗?我知道用javascript可以,但我现在要做的不是通过Web,而是直接用php脚本本身去获取。

剪贴板中的图片:意思是截图后复制到剪贴板,又或者是从网页中右击图片→复制图片(注意不是复制图片链接,是复制图片)这样复制到剪贴板中的:
clipboard.png]

如果使用系统的剪贴板函数是不行的,比如Mac的pbpaste,win的clip,Linux的xsel都只能处理剪贴板中的内容为纯文本的情况,如果是图片,它们获取不到任何内容。

google了好久也没查出来,所以想来问问大家。

关注 3 回答 3

xiebruce 评论了文章 · 2019-04-23

markdown博客图床上传的艰辛之路

markdown用着很爽吧,但是图片存哪呢? 写给所有写静态博客,又想搞个图床的人。

1. 适用场景

假如你用github page用markdown写个人博客的话,而你正好又用到一些图床的话,那你可以继续看下去。

2. 图床分类

图床可以分为两类:

  1. 付费类:云服务提供的对象存储: 例如七牛、阿里云提供的对象存储
  2. 免费类:专门的图床网站: 例如sm.ms, 路过图床,极简图床类似的,一般都是免费。优点是免费,缺点图片丢了就丢了,网站挂了就挂了,毕竟人家又没收你的钱

先说云服务提供的对象存储。

2.1. 七牛云

七牛图床也是推荐比较多的。而且七牛OSS在认证过后提供免费的10G存储空间,你看到的是免费10G存储空间

但是还有些信息没有告诉你。

  1. 免费的仅仅是存储空间,流量费超标了,还是要另算费用的哟
  2. 免费提供的外链仅仅是HTTP, HTTPS可是不免费的哟
  3. 免费提供的图片的外链是测试的域名,30天后会被回收的哟。也就是说,如果你用测试域名,那么你的图片很可能不知哪天就无法访问了。当然了,你也可以绑定一个正式的域名,但是你需要买个域名,对这个域名进行域名备案、公安网备案。如果你仅仅是为github pages搞个图床,那备案之路是不容易的就好比你想吃个茶叶蛋,但是小卖部老板要求你要写出一篇不少于800字的文章,从鸡蛋的外壳上去证明这只母鸡产下这枚蛋的心情。你要考虑是否值得。

2.2. 阿里云

如果你用阿里云的对象存储,阿里云是没有免空间的,但是其实空间并不贵,我之前买的9块钱40G一年的空间。而且阿里云提供正式的外链域名,域名是不会被回收的。

但是如果你以为阿里云很划算的话,你就很傻很天真了。

阿里云的对象存储计费是慢复杂的,而且不便宜。

阿里云OSS计费由四个部分组成: 存储费用 + 流量费用 + 请求费用 + 数据处理费用

至于具体计费细节我就不多说了,只说一个真实的故事。

七牛云给出测试域名回收通告之后,当天我就把500多张图片,大概24MB左右,全部迁移到阿里云OSS。当晚凌晨左右,正在躺在床上看灌篮高手的正起劲的我,突然收到阿里云OSS欠费通知。于是我虎躯一震,翻身下床,打开电脑,还了欠费,删了OSS。

总之,天下没有免费的午餐,出来混,总是要还的。

2.3. 又拍云

又拍云提供的外链,也是需要绑定域名的,而且域名需要备案。

2.4. 专门的图床网站

专门的图床网站,一般都是免费的。但是免费的,除非站长能力超强、票子超多,否则没有盈利模式的话,早晚可能还是免不了无法访问的结局。

详情可以看一下, 盘点一下免费好用的图床

3. 为了方便、还是为了折腾

给markdown图片一个图床,出发点是为了方便。为了markdown在迁移时,图片不会无法访问。

但是我觉得在这个出发点上,我越绕越远。为了方便,而折腾出一系列麻烦事。

4. 解决思路

  1. 博客尽量少加图片
  2. 尽量将图片放在博客目录下,不使用图床
  3. 对于不重要的图片,可以使用免费图床
  4. 可以购买一些付费的专门的图床服务
  5. 或者干脆使用github issue写博客,它是支持图片上传的
  6. 或者就sf,或者一些博客平台写博客
  7. 各种支持将图片上传到各个图床的工具也层出不穷,小心着用

5. 结论

  • 天下没有免费的午餐,我妈妈曾经在平多多上买了几分钱的床单,收货后觉得连尿布都不如。(我是笑着劝她不要买😁)
  • 出来混,最后总要还的
  • 如无必要,勿增实体。不要为了简单,反而让事情变得更复杂。奥卡姆剃刀原理
查看原文

认证与成就

  • 获得 1 次点赞
  • 获得 5 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 5 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2016-03-08
个人主页被 339 人浏览