Help us understand the problem. What is going on with this article?

GyazoとImgurのapiを使ってストレージを節約 with Vue

More than 1 year has passed since last update.

スクリーンショット (64).png
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から使用できます。

.env.local
VUE_APP_GYAZO='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
VUE_APP_IMGUR='zzzzzzzzzzzz'

コンポーネント

Uploader.vuepropsapiというオブジェクト変数を作ります。
親コンポーネントから渡した例

App.vue
<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>
Uploader.vue
<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>
ErgoFriend
美好くん
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした