本文目录

简介#

本博客的老读者可能会发现一个有意思的点:本站的 logo 似乎每天都会换一只新的猫猫头像。

于是笔者索性将其封装为一个开放的 API 托管至 Cloudflare Workers,方便各位读者免费调用。

使用指南#

基本信息#

API 端点: https://random-cat-assets-r2.hats-land.com/
速率限制: 30 RPM/IP (每IP每分钟30次请求)
响应格式: WebP, PNG, JSON 可选

直接引用图片#

GET https://random-cat-assets-r2.hats-land.com/api/v1/images

API 默认根据浏览器请求信息自适应返回 WebP 还是 PNG,如果你想指定返回的图片格式,可以添加以下参数:

  • ?format=png 强制返回 PNG 格式的图片
  • ?format=webp 强制返回 WebP 格式的图片

JSON API#

请求#

GET https://random-cat-assets-r2.hats-land.com/api/v1/json

响应#

JSON API 示例返回:

JSON
{
  "url": {
    "png": "https://s3-apac.hats-land.com/cat-assets/avatar/pb-5767334.png",
    "webp": "https://s3-apac.hats-land.com/cat-assets/avatar/pb-5767334.webp"
  },
  "width": 853,
  "height": 853
}

小贴士#

  1. 此 API 并不保证 SLA 可用性,请提前处理可能遇到的错误。
  2. 请尽量选择 WebP 格式,目前浏览器中除了 IE 均支持 WebP。

常见问题#

这个 API 适合生产环境直接依赖吗?#

不建议将其作为唯一头像来源。它更适合默认头像、占位图等轻量场景,生产环境建议做缓存和降级逻辑。

什么时候应优先选择 JSON 接口?#

当你需要拿到图片尺寸、做前端自定义渲染或后续处理时,优先使用 /api/v1/json,这样可以同时拿到 png/webp 地址与宽高信息。

为什么推荐优先使用 WebP?#

WebP 通常能在接近质量下显著降低体积,减少页面加载时间和带宽开销,适合头像这类高频资源。

示例代码#

你可以使用以下代码示例以实现快速嵌入这个 api,例如控制面板中的默认头像。(可选择不同语言哦)

原生 Fetch 实现
(()=>{
  const getRandomCat = () => 
    fetch('https://random-cat-assets-r2.hats-land.com/api/v1/json', {
      headers: { 'Accept': 'application/json' }
    })
    .then(r => r.json())
    .then(d => {
      const i = new Image();
      i.src = d.url.webp; // 可选 d.url.png
      i.alt = 'Random Cat Avatar';
      document.querySelector('.random-cat')?.replaceChildren(i);
    })
    .catch(e => console.error('RandomCat fetch failed:', e));

  document.addEventListener('DOMContentLoaded', getRandomCat);
})();
jQuery.js 实现
$(document).ready(() => {
  $.ajax({
    url: 'https://random-cat-assets-r2.hats-land.com/api/v1/json',
    method: 'GET',
    dataType: 'json',
    headers: { 'Accept': 'application/json' }
  })
  .done(data => {
    const img = $('<img>', {
      src: data.url.webp, // 可选 data.url.png
      alt: 'Random Cat Avatar'
    });
    $('.random-cat').empty().append(img);
  })
  .fail(err => console.error('RandomCat fetch failed:', err));
});
原生 xhr 实现
(()=>{
  const xhr = new XMLHttpRequest();
  xhr.open('GET', 'https://random-cat-assets-r2.hats-land.com/api/v1/json');
  xhr.setRequestHeader('Accept', 'application/json');
  
  xhr.onload = function() {
    if (xhr.status === 200) {
      const data = JSON.parse(xhr.responseText);
      const img = new Image();
      img.src = data.url.webp; // 可选 data.url.png
      img.alt = 'Random Cat Avatar';
      document.querySelector('.random-cat')?.replaceChildren(img);
    }
  };
  
  xhr.onerror = function() {
    console.error('RandomCat fetch failed:', xhr.statusText);
  };
})();
Vue 3
<template>
  <div class="random-cat">
    <img v-if="catUrl" :src="catUrl" alt="Random Cat Avatar" />
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const catUrl = ref('')

const getRandomCat = async () => {
  try {
    const res = await fetch('https://random-cat-assets-r2.hats-land.com/api/v1/json', {
      headers: { 'Accept': 'application/json' }
    })
    const data = await res.json()
    catUrl.value = data.url.webp // 可选 data.url.png
  } catch (err) {
    console.error('RandomCat fetch failed:', err)
  }
}

onMounted(getRandomCat)
</script>
React 18
import { useState, useEffect } from 'react'

function RandomCat() {
  const [catUrl, setCatUrl] = useState('')

  useEffect(() => {
    fetch('https://random-cat-assets-r2.hats-land.com/api/v1/json', {
      headers: { 'Accept': 'application/json' }
    })
      .then(r => r.json())
      .then(d => setCatUrl(d.url.webp)) // 可选 d.url.png
      .catch(e => console.error('RandomCat fetch failed:', e))
  }, [])

  return (
    <div className="random-cat">
      {catUrl && <img src={catUrl} alt="Random Cat Avatar" />}
    </div>
  )
}

export default RandomCat;
Svelte
<script>
  import { onMount } from 'svelte'
  
  let catUrl = ''
  
  onMount(async () => {
    try {
      const res = await fetch('https://random-cat-assets-r2.hats-land.com/api/v1/json', {
        headers: { 'Accept': 'application/json' }
      })
      const data = await res.json()
      catUrl = data.url.webp // 可选 data.url.png
    } catch (err) {
      console.error('RandomCat fetch failed:', err)
    }
  })
</script>

<div class="random-cat">
  {#if catUrl}
    <img src={catUrl} alt="Random Cat Avatar" />
  {/if}
</div>

HTML 使用示例#

HTML
<div class="random-cat" style="aspect-ratio:1/1"></div>

参考资料#

相关阅读#

版权信息 (点击展开)
CSHARP
Copyright (c) @ Hat's Blog www.hats-land.com
Released Date @ 2024-09-26 '/archives/technology/open-api-for-random-cat-avatars'
GPG Signature: 'https://www.hats-land.com/gpg-public.txt' (F166C5F4F897B96A07390B8574E3D911A0E70FEC)

// -----BEGIN PGP MESSAGE-----

// hF4DYvdQZ6S+TycSAQdA4YLsG2kv3qaa0J5LKHRD56rI8wna3OoKIwnHVzOiQCww
// axDk+KcrP3YULoLr7857CluyUtM+UW/Zyg9F0WYzDgeG9aPBMlh/W2eKWQ9qdDeh
// 1MCCAQkCECgQXU6drqBDjsv3t9nRLpMS/aMGtZ5/PrYRPROymKdDuSz48qiQQkHo
// XBtf2goIqYwYngpXD/b9F+vJ09O1UhxKCZUllIhMArM/GcUJTKmWsCGwp7YA/noW
// zuNVud4K34PUiodjvuyEIsEP/8E2C32FG4MtPOkYJ3Q5VNNliq3nh7Q/BCOaGSKb
// JpsezETOmxbwATVK6NphwBeEWVWA0wcHghSTj8itDNHH3WBeUwINptcpQ66wzuJ6
// gq5pt3wQ77d+gcHUW8yXk8i6F3eRS1q1qmc5/hQKlBWNsC+Xo+l7VJOsd2/sfkjh
// LAA84DyJPkyt3TAUyfMlv5WHoCBd3hgjHQFNMf+X1j8zmusc5qO2oJTp6DAfMgs9
// CVQvIWPgM64jTYFJYz+RdPSaevJD1HEuiNaY7KtCUIJfA1RMYw==
// =ahI2
// -----END PGP MESSAGE-----