DEMOページ https://gyazo-imgur.netlify.com/
GitHub https://github.com/ErgoFriend/gyazo-imgur
画像をアップロードしてgyazoもしくはimugrのurlを返してくれます。
書いてる途中にエンコードすればいいのかって思いましたけど、どうなんでしょうかねその辺。
ドキュメント
Gyazo
ドキュメント https://gyazo.com/api?lang=ja
アップロード エンドポイント https://upload.gyazo.com/api/upload
Imgur
ドキュメント https://apidocs.imgur.com/
アプリケーションを作成する https://api.imgur.com/oauth2/addclient
アップロード エンドポイント https://api.imgur.com/3/image
JavaScript
javascriptでapiを利用する
今回はfetchを使用してます。
Gyazoにアップロードする際に、Authorization = 'Client-ID ' + apiKey;
をヘッダーに含めてしまうとAccess-Control-Allow-Originエラーが出てしまいまいした。
なので、Vueでは条件分岐させています。
if (this.api.service == 'gyazo') {
data.append('imagedata', files[0]);
data.append('access_token', apiKey);
} else {
data.append('image', files[0]);
content.headers.Authorization = 'Client-ID ' + apiKey;
}
// https://api.imgur.com/3/image
// https://upload.gyazo.com/api/upload
const apiUrl = '';
// https://imgur.com/account/settings/apps
// https://gyazo.com/oauth/applications
const apiKey = '';
// Common
let data = new FormData();
let content = {
method: 'POST',
headers: {
Accept: 'application/json'
},
body: data,
mimeType: 'multipart/form-data'
};
// Gyazo
data.append('imagedata', files[0]);
data.append('access_token', apiKey);
// Imgur
data.append('image', files[0]);
content.headers.Authorization = 'Client-ID ' + apiKey; // Don't include gyazo api
fetch(apiUrl, content)
.then(
response => response.json() // if the response is a JSON object
)
.then(success => {
console.log(success);
console.log(success.url); // Gyazo API
console.log(success.data.link); // Imgur API
})
.catch(
error => console.log(error) // Handle the error response object
);
Vue
環境変数
GyazoとImgurのAPIトークンはtoken: process.env.VUE_APP_GYAZO
のように環境変数から読み込んでいます。
環境変数を使うには、プロジェクトルートに.env.local
というファイルを作成します。(package.json
があるとこ)
変数名の最初にVUE_APP_
を付けることでvueから使用できます。
VUE_APP_GYAZO='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
VUE_APP_IMGUR='zzzzzzzzzzzz'
コンポーネント
Uploader.vue
のprops
にapi
というオブジェクト変数を作ります。
親コンポーネントから渡した例
<template>
<div id="app">
<Uploader class="api" :api="gyazo"/>
<Uploader class="api" :api="imgur"/>
</div>
</template>
<script>
import Uploader from './components/Uploader.vue';
export default {
name: 'app',
components: {
Uploader
},
data() {
return {
imgur: {
service: 'imgur',
url: 'https://api.imgur.com/3/image',
token: process.env.VUE_APP_IMGUR,
logo: 'data:image/jpeg;base64,xxxxxxxxxxxxxxxxxxxxx'
},
gyazo: {
service: 'gyazo',
url: 'https://upload.gyazo.com/api/upload',
token: process.env.VUE_APP_GYAZO,
logo: 'https://i.imgur.com/ylzMVIk.png'
}
};
}
};
</script>
<template>
<div class="api_container">
<div style="height: 160px;">
<img :src="api.logo" style="max-width: 300px;"/>
</div>
<br>
<input v-show="!image_url" type="file" id="image_file" @change="onFileChange" class="imgur" accept="image/*" required/>
<button v-show="image_url" type="button" @click="removeImage">取り消す</button>
<br>
<p>URL: {{ image_url }}</p>
<br>
<div style="height: 300px;">
<img :src="image_thum" id="image_thum" style="max-width: 300px;"/>
</div>
</div>
</template>
<script>
export default {
props: {
api: {
type: Object,
logo: String,
url: String,
token: String,
service: String
}
},
data() {
return {
loading_gif:
'https://cdn-images-1.medium.com/max/1600/1*9EBHIOzhE1XfMYoKz1JcsQ.gif',
image_thum_sample:
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTaE2sVZUD0TFLL7ix68tjo2PG0cgxb_NFR65Thfr_VuC45yGfT',
image_thum:
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTaE2sVZUD0TFLL7ix68tjo2PG0cgxb_NFR65Thfr_VuC45yGfT',
image_url: null
};
},
methods: {
onFileChange: function(e) {
let files = e.target.files || e.dataTransfer.files;
if (!files.length) {
return;
}
const apiUrl = this.api.url;
const apiKey = this.api.token;
this.image_thum = this.loading_gif;
this.image_url = ' アップロードしています...';
let data = new FormData();
let content = {
method: 'POST',
headers: {
//Authorization: 'Client-ID ' + apiKey,
Accept: 'application/json'
},
body: data,
mimeType: 'multipart/form-data'
};
if (this.api.service == 'gyazo') {
console.debug('gyazo');
data.append('imagedata', files[0]);
data.append('access_token', apiKey);
} else {
console.debug('imgur');
data.append('image', files[0]);
content.headers.Authorization = 'Client-ID ' + apiKey;
}
fetch(apiUrl, content)
.then(
response => response.json() // if the response is a JSON object
)
.then(
success => {
console.log(success);
if (this.api.service == 'gyazo') {
console.log(success.url);
this.image_url = success.url;
} else {
console.log(success.data.link);
this.image_url = success.data.link;
}
this.createImage(files[0]);
} // Handle the success response object
)
.catch(
error => console.log(error) // Handle the error response object
);
},
createImage(file) {
let reader = new FileReader();
reader.onload = e => {
this.image_thum = e.target.result;
};
reader.readAsDataURL(file);
},
removeImage() {
this.image_url = '';
document.getElementById('image_file').value = '';
this.image_thum = this.image_thum_sample;
}
}
};
</script>