GitHub API 介紹
需要用到的是功能十分強大的 GitHub API,這裡只需要 建立或更新檔案內容 介面。
建立或更新檔案內容
請求地址:api.github.com/repos/{owner}/{repo}/contents/{path}
請求方式:
PUT
引數
名稱 | 型別 | 位置 | 描述 |
---|---|---|---|
accept |
string | header | 建議設定為 application/vnd.github.v3+json |
owner |
string | path | 使用者名稱 |
repo |
string | path | 倉庫名 |
path |
string | path | 檔案儲存路徑 |
message |
string | body | 必填 - The commit message |
content |
string | body | 必填 - 新檔案內容,使用 Base64 編碼 |
sha |
string | body | 如果要更新檔案,則必填 - 被替換檔案的 blob SHA |
branch |
string | body | 分支名稱 - 版本庫的預設分支通常是 master |
committer |
object | body | 提交人 - 預設為已認證的使用者 |
author |
object | body | 檔案的作者 - 預設為 committer ,如省略 committer ,則為認證的使用者 |
committer
物件的屬性
名稱 | 描述 |
---|---|
name (string) |
必填 - 提交的作者或提交者的名字。如果省略 name 會收到 422 狀態程式碼 |
email (string) |
必填 - 提交的作者或提交者的電子郵件。如果省略 email 會收到 422 狀態程式碼 |
date (string) |
author
物件的屬性
名稱 | 描述 |
---|---|
name (string) |
必填 - 提交的作者或提交者的名字。如果省略 name 會收到 422 狀態程式碼 |
email (string) |
必填 - 提交的作者或提交者的電子郵件。如果省略 email 會收到 422 狀態程式碼 |
date (string) |
鑑權
官方提供了三種方式:
Basic authentication - 使用者名稱和密碼
OAuth2 Token - token
OAuth2 key/secret - client_id 和 client_secret (只支援查詢)
推薦使用第 2 種方式。
設定 token
Settings > Developer settings > Personal access tokens > Generate new token
生成的 token 要儲存好,只顯示一次。
建立倉庫
一定要把倉庫設定為公開的,目的是能夠使用 jsDelivr CDN 加速。
使用 GitHub 倉庫作為圖床,存在的問題是國內訪問 GitHub 的速度很慢,可以利用 jsDelivr CDN 來加速訪問。jsDelivr 是一個免費開源的 CDN 解決方案,該平臺是首個打通中國大陸與海外的免費 CDN 服務,擁有中國政府頒發的 ICP 許可證,無須擔心中國防火牆問題而影響使用。使用 jsDelivr 加速訪問,需要將自定義域名設定為 https://cdn.jsdelivr.net/gh/使用者名稱/圖床倉庫名
。
Laravel 程式碼
需要設定幾個配置引數,建議放到 .env
檔案中。
GITHUB_FILE_REPOSITORY=YOUR_REPOSITORY
GITHUB_FILE_BRANCH=master
GITHUB_FILE_TOKEN=YOUR_TOKEN
GITHUB_FILE_PATH=YOUR_PATH
GITHUB_FILE_NAME=1
GITHUB_FILE_COMMIT_MESSAGE=”YOUR COMMIT MESSAGE”
然後在 config
下建立一個配置檔案,我建立了一個 github-image.php
配置檔案
<?php
return [
/**
- GitHub 倉庫
- /
‘repository’ => env(‘GITHUB_FILE_REPOSITORY’, ‘’),
/** - 分支
- /
‘branch’ => env(‘GITHUB_FILE_BRANCH’, ‘master’),
/** - Personal access token
- /
‘token’ => env(‘GITHUB_FILE_TOKEN’, ‘’),
/** - 儲存路徑,若 GitHub 倉庫中沒有,則自動建立
- /
‘path’ => env(‘GITHUB_FILE_PATH’, ‘’),
/** - 自定義域名
- 若不定義則使用 raw.githubusercontent.com/ 出於某些原因可能圖片載入會很慢,甚至失敗
- 建議使用 cdn.jsdelivr.net/gh/ 加速
- /
‘domain’ => env(‘GITHUB_FILE_DOMAIN’, ‘cdn.jsdelivr.net/gh/'),
/** - 檔案命名
- 1 - 以時間戳方式重新命名
- 2 - 以隨機字串方式重新命名
- 3 - 保持原名
- ……
- /
‘name’ => env(‘GITHUB_FILE_NAME’, 1),
/** - commit 記錄
- /
‘commit_message’ => env(‘GITHUB_FILE_COMMIT_MESSAGE’, ‘’),
];
建立一個 Trait
以複用上傳功能
<?php
namespace App\Traits;
use Exception;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Http;
trait UploadToGithub
{
public function uploadToGithub($file, $message = ‘’)
{
$path = config(‘github-file.path’) . ‘/‘ . $this->setFileName($file);
$repository = config(‘github-file.repository’);
if ($file->isValid()) {
$url = “https://api.github.com/repos/$repository/contents/$path";
$response = Http::withToken(config(‘github-file.token’))->put($url, [
‘message’ => $message ?: config(‘github-file.commit_message’),
‘content’ => base64_encode(file_get_contents($file))
]);
// 上傳失敗丟擲一個錯誤,成功則返回 JSON
$body = $response->throw()->json();
// 上傳成功後 GitHub API 返回的是 201,其實有了上一步這裡的判斷可以省略
if ($response->successful()) {
return config(‘github-file.domain’)
? rtrim(config(‘github-file.domain’), ‘/‘) . ‘/‘ . trim($repository, ‘/‘) . ‘/‘ . ltrim($body[‘content’][‘path’], ‘/‘)
: $body[‘content’][‘download_url’];
}
}
throw new Exception(‘未發現圖片’);
}
/**
- 生成圖片名稱
- @param $file
- @return mixed|string
- /
private function setFileName($file)
{
switch (config(‘github-file.name’)) {
case 1:
return date(‘YmdHis’, time()) . ‘.’ . $file->getClientOriginalExtension();
case 2:
return Str::random(32) . ‘.’ . $file->getClientOriginalExtension();
case 3:
default:
return $file->getClientOriginalName();
}
}
}
在需要的地方使用 UploadToGithub
use UploadToGithub;
public function updload(Request $request)
{
$url = $this->uploadToGithub($request->file(‘file-field-name’));
return response()->json([
‘code’ => 200,
‘message’ => ‘上傳成功’,
‘data’ => [
‘url’ => $url
]
]);
}
本文章首發於 不二部落格 更多用法可以參閱 使用 PicGo + GitHub 搭建個人免費圖床 和 Typora + PicGo 打造舒爽的寫作體驗。
本作品採用《CC 協議》,轉載必須註明作者和本文連結