使用Golang展示API URL中的图片

使用Golang展示API URL中的图片 在使用Go语言的REST API时,我获取到了一个现成的图片URL并显示了图片,但是当我使用自己Google Drive或Google上的任何图片URL时,我的项目却无法获取到图片,可能是什么原因?

POST和GET代码

r.POST("/blog", func(c *gin.Context) {
		var blog Blog
		if err := c.ShouldBindJSON(&blog); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}

		// insert blog into database
		query := "INSERT INTO my_table (title, body, image, date) VALUES ($1, $2, $3, $4) RETURNING id"
		var id int
		err := db.QueryRow(query, blog.Title, blog.Body, blog.ImageURL, time.Now()).Scan(&id)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create blog"})
			return
		}

		c.JSON(http.StatusOK, blog)
	})

	// get blog by ID
	r.GET("/blog/:id", func(c *gin.Context) {
		var blog Blog
		id := c.Param("id")

		// get blog from database
		err := db.Get(&blog, "SELECT * FROM my_table  WHERE id=$1", id)
		if err != nil {
			if err == sql.ErrNoRows {
				c.JSON(http.StatusNotFound, gin.H{"error": "blog not found"})
			} else {
				c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get blog"})
			}
			return
		}

		c.JSON(http.StatusOK, blog)
	})

app.js:

function App() {
  const [post, setPost] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await axios.get('http://localhost:8080/blog/5'); // replace "id" with the desired id
        setPost(response.data);
      } catch (error) {
        setError(error.message);
      }
    }
    fetchData();
  }, []);

  if (error) {
    return <div>{error}</div>;
  }

  if (!post) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.body}</p>
      <img src={post.image} alt={post.title} />
      <p>{new Date(post.date).toLocaleString()}</p>
      <p>ID: {post.id}</p>
    </div>
  );
}

更多关于使用Golang展示API URL中的图片的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

我正在使用Postman发送数据,并将从数据接收到的内容写入屏幕。

更多关于使用Golang展示API URL中的图片的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


当它获取自己的图片URL时不起作用,但当我使用一个现成的图片URL API时却可以工作。

post.image 这个 API 具体返回什么?你是如何通过 POST 请求来创建博客文章的?

Coding_Yaz:

但是我在自己的谷歌硬盘或谷歌上获取任何图片链接

我对这一点感到困惑。该API为那个图片链接返回了什么?渲染出的HTML有什么问题?

问题可能出在Google Drive的图片URL需要特定的访问权限或处理方式。Google Drive的图片URL通常是带有访问令牌的共享链接,直接作为img标签的src可能无法正常加载。

以下是几种可能的原因和解决方案:

  1. Google Drive URL格式问题:Google Drive的共享链接需要转换为直接访问的格式。
  2. 访问权限限制:Google Drive链接可能需要授权或设置公开访问。
  3. CORS限制:浏览器可能阻止跨域资源加载。

解决方案示例

在Go后端添加一个代理端点来获取图片数据:

r.GET("/proxy-image", func(c *gin.Context) {
    imageURL := c.Query("url")
    if imageURL == "" {
        c.JSON(http.StatusBadRequest, gin.H{"error": "URL parameter is required"})
        return
    }

    // 创建HTTP客户端
    client := &http.Client{
        Timeout: 10 * time.Second,
    }

    // 设置请求头
    req, err := http.NewRequest("GET", imageURL, nil)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create request"})
        return
    }

    // 添加User-Agent头,模拟浏览器请求
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")

    // 发送请求
    resp, err := client.Do(req)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch image"})
        return
    }
    defer resp.Body.Close()

    // 检查响应状态
    if resp.StatusCode != http.StatusOK {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "Image server returned error"})
        return
    }

    // 读取图片数据
    imageData, err := io.ReadAll(resp.Body)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read image data"})
        return
    }

    // 设置响应头
    c.Header("Content-Type", resp.Header.Get("Content-Type"))
    c.Header("Content-Length", fmt.Sprint(len(imageData)))
    
    // 返回图片数据
    c.Data(http.StatusOK, resp.Header.Get("Content-Type"), imageData)
})

前端修改

function App() {
  const [post, setPost] = useState(null);
  const [error, setError] = useState(null);
  const [imageUrl, setImageUrl] = useState(null);

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await axios.get('http://localhost:8080/blog/5');
        setPost(response.data);
        
        // 如果是Google Drive链接,使用代理
        if (response.data.image && response.data.image.includes('drive.google.com')) {
          const proxyUrl = `http://localhost:8080/proxy-image?url=${encodeURIComponent(response.data.image)}`;
          setImageUrl(proxyUrl);
        } else {
          setImageUrl(response.data.image);
        }
      } catch (error) {
        setError(error.message);
      }
    }
    fetchData();
  }, []);

  if (error) {
    return <div>{error}</div>;
  }

  if (!post) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.body}</p>
      {imageUrl && <img src={imageUrl} alt={post.title} />}
      <p>{new Date(post.date).toLocaleString()}</p>
      <p>ID: {post.id}</p>
    </div>
  );
}

Google Drive链接转换函数(可选):

func convertGoogleDriveURL(shareURL string) string {
    // 将Google Drive共享链接转换为直接下载链接
    // 示例:https://drive.google.com/file/d/FILE_ID/view?usp=sharing
    // 转换为:https://drive.google.com/uc?export=view&id=FILE_ID
    
    re := regexp.MustCompile(`/d/([^/]+)`)
    matches := re.FindStringSubmatch(shareURL)
    if len(matches) > 1 {
        fileID := matches[1]
        return fmt.Sprintf("https://drive.google.com/uc?export=view&id=%s", fileID)
    }
    return shareURL
}

在存储图片URL时使用转换函数:

// 在POST处理函数中
convertedImageURL := convertGoogleDriveURL(blog.ImageURL)
err := db.QueryRow(query, blog.Title, blog.Body, convertedImageURL, time.Now()).Scan(&id)

这些修改可以解决Google Drive图片无法显示的问题。代理端点可以处理各种外部图片URL,包括需要特殊处理的Google Drive链接。

回到顶部