You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Koa后端+前端表单对接Dog API技术问题求助

解决方案

1. 前端表单与请求逻辑调整

确保表单正确提交搜索词并处理后端响应:

<form id="dogSearchForm">
  <input type="text" name="breed" placeholder="输入犬种(比如golden retriever)" required>
  <button type="submit">搜索图片</button>
</form>
<div id="dogImages"></div>

<script>
document.getElementById('dogSearchForm').addEventListener('submit', async (e) => {
  e.preventDefault();
  const breed = document.querySelector('input[name="breed"]').value;
  
  try {
    const res = await fetch('/api/search-dog', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ breed })
    });
    
    const data = await res.json();
    const dogImagesDiv = document.getElementById('dogImages');
    dogImagesDiv.innerHTML = '';
    
    data.message.forEach(imgUrl => {
      const img = document.createElement('img');
      img.src = imgUrl;
      img.alt = breed;
      img.style.width = '200px';
      dogImagesDiv.appendChild(img);
    });
  } catch (err) {
    console.error('请求失败:', err);
  }
});
</script>

2. Koa后端核心实现

首先安装依赖:

npm install koa koa-bodyparser isomorphic-fetch

编写后端代码(示例文件server.js):

const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const fetch = require('isomorphic-fetch');

const app = new Koa();

// 解析JSON请求体,这是Koa与Express的核心差异之一
app.use(bodyParser());

// 处理犬种搜索接口
app.use(async (ctx) => {
  if (ctx.path === '/api/search-dog' && ctx.method === 'POST') {
    const { breed } = ctx.request.body;
    
    if (!breed) {
      ctx.status = 400;
      ctx.body = { error: '请提供犬种名称' };
      return;
    }
    
    try {
      // 适配Dog API的路径规则:复合犬种转斜杠分隔(如golden retriever → golden/retriever)
      const formattedBreed = breed.replace(/\s+/g, '/');
      const apiUrl = `https://dog.ceo/api/breed/${formattedBreed}/images`;
      
      const res = await fetch(apiUrl);
      const data = await res.json();
      
      if (data.status !== 'success') {
        ctx.status = 404;
        ctx.body = { error: '未找到对应犬种的图片' };
        return;
      }
      
      ctx.body = data;
    } catch (err) {
      ctx.status = 500;
      ctx.body = { error: '后端调用Dog API失败' };
      console.error('API调用错误:', err);
    }
  } else if (ctx.method === 'GET' && ctx.path === '/') {
    // 返回前端页面(若前端文件单独存放,可使用koa-static中间件托管)
    ctx.type = 'html';
    ctx.body = `
      <!DOCTYPE html>
      <html>
      <head>
        <title>犬种图片搜索</title>
      </head>
      <body>
        <form id="dogSearchForm">
          <input type="text" name="breed" placeholder="输入犬种(比如golden retriever)" required>
          <button type="submit">搜索图片</button>
        </form>
        <div id="dogImages"></div>
        <script>
          document.getElementById('dogSearchForm').addEventListener('submit', async (e) => {
            e.preventDefault();
            const breed = document.querySelector('input[name="breed"]').value;
            
            try {
              const res = await fetch('/api/search-dog', {
                method: 'POST',
                headers: {
                  'Content-Type': 'application/json',
                },
                body: JSON.stringify({ breed })
              });
              
              const data = await res.json();
              const dogImagesDiv = document.getElementById('dogImages');
              dogImagesDiv.innerHTML = '';
              
              data.message.forEach(imgUrl => {
                const img = document.createElement('img');
                img.src = imgUrl;
                img.alt = breed;
                img.style.width = '200px';
                dogImagesDiv.appendChild(img);
              });
            } catch (err) {
              console.error('请求失败:', err);
            }
          });
        </script>
      </body>
      </html>
    `;
  } else {
    ctx.status = 404;
    ctx.body = { error: '接口不存在' };
  }
});

const port = 3000;
app.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}`);
});

3. 关键注意事项

  • Koa请求体解析:Koa默认不处理请求体,必须通过koa-bodyparser中间件才能获取ctx.request.body中的参数,这是Express转Koa开发者常踩的坑。
  • Dog API路径适配:复合犬种名称需要转为斜杠分隔的格式,否则API会返回错误。
  • 错误边界处理:前后端都加入异常捕获,避免因网络问题或API返回异常导致页面崩溃。
  • 跨域问题:若前端与后端分离部署,需在Koa中添加koa-cors中间件配置跨域规则;本地开发时后端直接返回页面则无需处理。

启动后端测试:

node server.js

访问http://localhost:3000即可使用搜索功能。

内容的提问来源于stack exchange,提问作者Brendan F

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 02:55:31