加载资源时报错-ERR_CONNECTION_RESET,需要多次请求才能拿到资源的有效解决方案

初次加载资源时无法正常加载,需要多次刷新、请求才能拿到资源的有效解决方案

前言

在使用cloudinary进行图片上传并获取图片链接作为用户头像时发现,图片链接网址初次加载会报错:ERR_CONNECTION_RESET必须刷新几次才能获取到,原因可能是cloudinary没有国内的节点,而我用的是在新加坡的节点,所以会导致初次加载的时候被重定向。而这个错误会直接导致用户头像无法加载,因为在img中此链接只会被在初始化的时候加载一次,而此博客就是为了解决此问题让图片正常加载。

正文

我的思路就是监听图片地址是否能正常获取,若是获取失败则一直刷新直到图片正常加载,具体看下面代码:

修改前:

import { signOut, useSession } from 'next-auth/react';
import Link from 'next/link'
import React from 'react'
import { SessionData } from '../lib/type';
import { Logout } from '@mui/icons-material';
const handleLogout = () => {
  signOut({ callbackUrl: '/auth/login' });
}
const TopBar = () => {
  const { data: session } = useSession();
  const user = session?.user as SessionData | null;
  return (
    <div className='bg-white h-9 border-x-1 flex justify-between'>

          <p className='text-center mt-2 ml-2 font-sans text-small antialiased font-bold'>NextChat</p>
          <div className='flex'>
            <Link rel="stylesheet" href="/chats/profile">
              <img
                src={user?.image || "/images/person.jpg"}
                alt="image"
                className="w-8 h-8 rounded-full mt-[2px]" 
              />
            </Link>
            
            <div className='mx-4'>
              <p className='text-center font-sans text-small antialiased font-bold'>{user?.username}</p>
              <p className='text-center font-sans text-mm antialiased font-bold text-gray-500'>{user?.email}</p>
            </div>
            <Logout sx={{ color: "#737373", cursor: "pointer" }} onClick={handleLogout} className='mt-1 mr-4'/>
          </div>
        </div>
  )
}
export default TopBar

修改后:

import { signOut, useSession } from 'next-auth/react';
import Link from 'next/link'
import React, { useEffect, useRef } from 'react'
import { SessionData } from '../lib/type';
import { Logout } from '@mui/icons-material';
const handleLogout = () => {
  signOut({ callbackUrl: '/auth/login' });
}
const TopBar = () => {
  const { data: session } = useSession();
  const user = session?.user as SessionData | null;
  const imageRef = useRef<HTMLImageElement | null>(null);

  const handleImageError = () => {
    if (imageRef.current) {
      imageRef.current.src = user?.image || "/images/person.jpg";
    }
  };

  useEffect(() => {
    if (imageRef.current) {
      imageRef.current.onerror = handleImageError;
    }
  }, [user?.image]);

  return (
    <div className='bg-white h-9 border-x-1 flex justify-between'>

          <p className='text-center mt-2 ml-2 font-sans text-small antialiased font-bold'>NextChat</p>
          <div className='flex'>
            <Link rel="stylesheet" href="/chats/profile">
              <img
                ref={imageRef}
                src={user?.image || "/images/person.jpg"}
                alt="image"
                className="w-8 h-8 rounded-full mt-[2px]" 
              />
            </Link>
            
            <div className='mx-4'>
              <p className='text-center font-sans text-small antialiased font-bold'>{user?.username}</p>
              <p className='text-center font-sans text-mm antialiased font-bold text-gray-500'>{user?.email}</p>
            </div>
            <Logout sx={{ color: "#737373", cursor: "pointer" }} onClick={handleLogout} className='mt-1 mr-4'/>
          </div>
        </div>
  )
}

export default TopBar

在这个修改后的代码中,我定义了一个名为 imageRefuseRef 来存储图像元素的引用。然后,我使用 useEffect 钩子来监听 user?.image 的变化,并在其变化时更新图像的 onerror 事件处理函数。当图像加载失败时,handleImageError 函数会被调用,重新设置图像的 src 属性为原始的 user?.image 或默认图片的路径,如果在处理函数 handleImageError 中将图片 src 重新设置为另一个同样会加载失败的图片地址,这会再次触发 onerror 事件。这样图片就会一直尝试重新加载,直到成功为止。

你可能感兴趣的:(前端开发,前端,javascript,react.js,前端框架,typescript,vue.js)