使用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
我正在使用Postman发送数据,并将从数据接收到的内容写入屏幕。
更多关于使用Golang展示API URL中的图片的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
当它获取自己的图片URL时不起作用,但当我使用一个现成的图片URL API时却可以工作。
post.image 这个 API 具体返回什么?你是如何通过 POST 请求来创建博客文章的?
问题可能出在Google Drive的图片URL需要特定的访问权限或处理方式。Google Drive的图片URL通常是带有访问令牌的共享链接,直接作为img标签的src可能无法正常加载。
以下是几种可能的原因和解决方案:
- Google Drive URL格式问题:Google Drive的共享链接需要转换为直接访问的格式。
- 访问权限限制:Google Drive链接可能需要授权或设置公开访问。
- 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链接。


