HTTP Status 404 的解决思路

本文详细解析了HTTP 404错误的原因及其解决办法,从URL的构成讲起,逐步深入到HTTP请求的全过程,帮助读者理解如何避免及解决404错误。

目录

维基百科:

什么是URL

一次完整Http请求

1)DNS域名解析 

2)发起TCP的3次握手,建立TCP连接

3) 建立TCP连接后发起http请求

4)服务器响应http请求,浏览器得到html代码

5)浏览器解析html代码,并请求html代码中的资源(如js、css、图片等)

6)浏览器对页面进行渲染呈现给用户

出现404的一些解决办法

持续更ing....


维基百科:

HTTP 404Not Found错误消息是HTTP的其中一种“标准回应消息”(HTTP状态码),此消息代表客户端在浏览网页时,服务器无法正常提供消息,或是服务器无法回应且不知原因。通常是因为用户所访问的对应网页已被删除被移动或从未存在。404也是互联网上最常见的错误之一。404错误消息可能与“server not found”(无法找到服务器)或其他类似消息产生混淆。

简单说,就是服务器中所请求的资源不存在,或者存在的情况下,我们发送的请求通过URL(统一资源定位符)在服务器没有找到所需资源。

什么是URL

出现404最常见的的是路径错误。让我们先了解下URL。

URL,(Uniform Resource Locator)统一资源定位符,又叫统一资源定位器、定位地址、URL地址,俗称网页地址或简称网址。正如其名,就是用于定位服务的资源在哪?发送的Request去哪里找,然后服务器再做出相应的逻辑响应(Response)。

统一资源定位符的标准格式如下:

[协议类型]://[服务器地址]:[端口号]/[资源层级UNIX文件路径][文件名]?[查询]#[片段ID]

统一资源定位符的完整格式如下:

[协议类型]://[访问资源需要的凭证信息]@[服务器地址]:[端口号]/[资源层级UNIX文件路径][文件名]?[查询]#[片段ID]

举个栗子:http://127.0.0.1:8080/f?kw=%BA%A3%D4%F4%CD%F5&fr=ala0&tpl=5

http,是协议;127.0.0.1,是我的服务器地址;8080,是服务器上的端口号;

/f,是路径;其中/ 分隔目录和子目录。

?kw=%BA%A3%D4%F4%CD%F5&fr=ala0&tpl=5,是查询。? 分隔实际的URL和参数,这里很容易出错。虽然数据(除了数字)都会转换成以UTF8的URL编码,& 用于参数间的分隔符,= 等于(不是赋值),初次之外,还有+表示空格,#表示书签。

格式需要注意的地方:

1)一般使用Tomcat和nginx等服务器启动的项目,需要查看端口是否正确。

2)协议名http/https,域名或者ip地址是否有误?

3)/分割符,以 / 区别路径中的每一个目录名称。这样我们我们可以根据URL一层层的去查找我们项目的目录,分析出现404可能的原因是否为路径错误或者资源不存在。

3)&表示的参数,可以预估其值是否达到预期。

一次完整Http请求

了解我们请求的过程有助于我们理解web的大体运行流程。

总体流程如下:

域名解析 --> 发起TCP的3次握手 --> 建立TCP连接后发起http请求 --> 服务器响应http请求,浏览器得到html代码 --> 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) --> 浏览器对页面进行渲染呈现给用户。

下面我们详细讲解下它们都干了些什么?

1)DNS域名解析 

dns是什么?将主机域名转换为ip地址,属于应用层协议,使用UDP传输。

dns工作原理:

一、主机向本地域名服务器的查询一般都是采用递归查询。

二、本地域名服务器向根域名服务器的查询的迭代查询。

1)  当用户输入域名时,浏览器先检查自己的缓存中是否 这个域名映射的ip地址,有解析结束。

2)若没命中,则检查操作系统缓存(如Windows的hosts)中有没有解析过的结果,有解析结束。

3)若无命中,则请求本地域名服务器解析( LDNS)。

4)若LDNS没有命中就直接跳到根域名服务器请求解析。根域名服务器返回给LDNS一个 主域名服务器地址。

5) 此时LDNS再发送请求给上一步返回的gTLD( 通用顶级域), 接受请求的gTLD查找并返回这个域名对应的Name Server的地址

6) Name Server根据映射关系表找到目标ip,返回给LDNS

7) LDNS缓存这个域名和对应的ip, 把解析的结果返回给用户,用户根据TTL值缓存到本地系统缓存中,域名解析过程至此结束

 

2)发起TCP的3次握手,建立TCP连接

tcp为什么要三次握手?谢希仁的《计算机网络》给出的解释是为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。三次握手过程:

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据。

有人说会不会因为丢包而导致404错误?可能性极小,来看看伟大的前人给TCP加了加特林,这里不得不提TCP是如何保证可靠传输的,与上面三次握手协议都是校招面试的重点。

  1. 三次握手。

  2. 将数据截断为合理的长度。应用数据被分割成 TCP 认为最适合发送的数据块(按字节编号,合理分片)

  3. 超时重发。当 TCP 发出一个段后,它启动一个定时器,如果不能及时收到一个确认就重发

  4. 确认应答:对于收到的请求,给出确认响应

  5. 校验和:校验出包有错,丢弃报文段,不给出响应

  6. 序列号:对失序数据进行重新排序,然后才交给应用层

  7. 丢弃重复数据:对于重复数据 , 能够丢弃重复数据

  8. 流量控制。TCP 连接的每一方都有固定大小的缓冲空间。TCP 的接收端只允许另一端发送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。

  9. 拥塞控制。当网络拥塞时,减少数据的发送。

3) 建立TCP连接后发起http请求

http是一个无状态的请求/响应协议,但是这不能满足现在的业务,所以有了cookie和session,它们都是用于保存状态的。

一个完整的HTTP请求报文包括请求行(request line)、请求头部(header)、空行和请求数据四个部分组成。如图所示:

我们也可以打开谷歌-->F12进入到调试模式-->Network-->查看信息。里面包含很多请求信息或者响应信息,我们也可以基于它们进行开发操作。

再让我们了解HTTP请求的常见方法:GET,POST,DELETE,TRACE ,CONNECT 。

GET只用在读取数据,不做修改,返回指定的页面
POST请求处理数据,一般用于修改,新增资源
DELETE删除所指定的资源
TRACE主要用于测试或诊断,不常用
CONNECT通常用于SSL加密服务器的链接,用于给能够将连接改为管道方式的代理服务器。

 

 

 

 

 

 

注:这里提一下cookie和session的区别(面试常考)

1,存储的位置不同。cookie:存放在客户端,session:存放在服务端。Session存储的数据比较安全

2,存储的数据类型不同。两者都是key-value的结构,但针对value的类型是有差异的

cookie:value只能是字符串类型,session:value是Object类型

3,存储的数据大小限制不同。cookie:大小受浏览器的限制,很多是是4K的大小, session:理论上受当前内存的限制,

4,生命周期的控制。cookie的生命周期当浏览器关闭的时候,就消亡了

(1)cookie的生命周期是累计的,从创建时,就开始计时,30分钟后,cookie生命周期结束,

(2)session的生命周期是间隔的,从创建时,开始计时如在30分钟,没有访问session,那么session生命周期被销毁.

4)服务器响应http请求,浏览器得到html代码

5)浏览器解析html代码,并请求html代码中的资源(如js、css、图片等)

html页面主要由domcssjavascript等部分构成,还可能引入imgiframe等其他资源。浏览器接收到html代码,可能是一份完整的文档,也可能是一个chunk,即开始解析。解析过程是先构建dom树,再根据dom树构建渲染树,最后浏览器将渲染树绘制到页面上。

6)浏览器对页面进行渲染呈现给用户

什么是渲染?渲染 在电脑绘图中是指用软件从模型生成图像的过程,也就是将我们Html的逻辑转换成我们肉眼可见的对象。具体课看博客:https://sylvanassun.github.io/2017/10/03/2017-10-03-BrowserCriticalRenderingPath/


出现404的一些解决办法

1)目录不能被引用。 排错方法:

在 Eclipse的“包资源管理器(Package Explorer)”检查文件存放的位置。由于META-INF

WEB-INF文件夹下的内容无法对外发布,所以,如果你引用了带这两个目录的文件,肯定是不允许。例如: http://localhost:8080/guestbook/WEB-INF/index.html就是错误的

文件位置存放错误

2)URL输入错误。排错方法:

首先,查看URL的IP地址和端口号是否书写正确。

其次,查看上下文路径是否正确 Project--------Properties------MyElipse-----Web-----

Web Context-root检查这个路径名称是否书写正确。

最后,检查一下文件名称是否书写正确。
3)未部署Web应用

4)Tomcat服务器中web.xml中的问题。 排错方法:

      如果你的web应用程序有多个jsp页面的话,当你点击你web应用程序的虚拟根目录时可能会出现404错 误,只是你只需要修改Tomcat服务器中web.xml       

 <init-param>

        <param-name>listings</param-name>

        <param-value>false(将其该为true)</param-value>

  </init-param>

补充说明:在6.0.18 版本error:“ The requested resource () is not available. ”

总是无法访问/myapp/*.jsp文件,可以将 /ROOT 中build.xml 文件copy 一份到myapp,  注意把里面所有的 ROOT 用 myapp 代替. 应该就OK.

5)WEB-INF下面必须要有几个固定的文件夹和文件   

 ±web.xml 该web app的配置文件

 ±lib 该web app用到的库文件

 ±classes存放编译好的servlet 

 请注意他们的名字,我曾经就由于把classes写成class,查错查了半宿还没解决,所以写这些的时候千万要仔细,要不会浪费更多的精力去查错。

6、如果要运行的不是.jsp文件,而是servlet(.class)文件,要配置web.xml(当然是WEB-INF下面的),加上以下字段: 

 <servlet>

      <servlet-name>HelloWorldServlet</servlet-name>

      <servlet-class>HelloWorldServlet</servlet-class>

 </servlet>

 <servlet-mapping>

      <servlet-name>HelloWorldServlet</servlet-name>
    
      <url-pattern>/HelloWorldServlet</url-pattern>

 </servlet-mapping>

其中的“HelloWorldServlet”改为你要运行的文件名

7)struts.xml配置错误,可能是你的Action值写错或者链接URL写错

下面是我自己的解决办法,很多书都是导入六个文件,我自己的话是多增加了commons-lang3-3.1.jar和javassist-3.11.GA.jar

增加commons-lang3-3.1.jar文件到啊WEB-INF/lib目录下,struts2最新的web开发包如下:

 

下载地址:http://download.youkuaiyun.com/detail/ahy1024/4626028

8)是否同一个应用启动了多个java应用服务,有时后台并没有关闭之前的服务,你又重新启动,,可能会报错404

 

持续更ing....

 

<think>首先,用户的问题是关于web页面偶尔出现HTTP Status 404 – Not Found错误的原因和解决办法。系统提示要参考站内引用,并尽可能多地参考用户上一次的问题和我的回答。 回顾引用内容: - 引用[1]:讨论Druid监控登录时出现404错误,解决方案包括降低Druid版本到1.1.10及以下,或者在配置文件中设置enabled: true。还提到将yml转为properties。 - 引用[2]:提到HTTP Status 404问题集合,强调MySQL驱动与MySQL版本必须保持一致,并给出了一个例子。 用户的上一次问题和我的回答:在之前的对话中,用户第一次查询是关于Druid监控的404错误,我提供了解决方案。现在,用户的问题是更一般的:web页面偶尔出现404错误。引用[1]和[2]都涉及404错误,但具体场景不同。 用户的需求:用户想查找web页面偶尔报HTTP Status 404 – Not Found错误的原因及解决方案。强调“偶尔”,意味着不是总是发生,而是有时发生。 现在,我需要基于引用和其他知识来回答。引用[1]和[2]提供了一些线索,但404错误的原因很多,我需要整理常见的、一般性的原因和解决方案。 常见的HTTP 404错误原因: 1. **URL路径错误**:请求的资源不存在于服务器上,可能是因为URL拼写错误或资源被移动。 2. **服务器配置问题**:如Apache、Nginx或应用服务器(如Tomcat)的配置错误。 3. **应用框架问题**:在Spring Boot等框架中,端点未正确配置。引用[1]中提到的Druid案例就是这种。 4. **版本兼容性问题**:如引用[1]中的Druid版本问题,或引用[2]中的JDBC驱动与数据库版本不匹配。 5. **资源部署问题**:Web应用部署时,某些文件未正确部署。 6. **临时问题**:如网络问题、服务器负载高导致资源暂时不可用,这可能解释“偶尔”发生。 7. **其他**:如缓存问题、CDN问题等。 针对“偶尔”发生,可能的原因包括: - 服务器重启或维护期间。 - 网络不稳定导致请求未到达正确服务器。 - 会话问题或负载均衡问题。 - 应用错误,如在某些条件下资源未被加载。 解决方案: 1. **检查URL**:确保请求的URL正确。 2. **验证配置文件**:如Spring Boot的application.yml/properties文件,确保端点启用。 3. **日志分析**:检查服务器日志和应用程序日志,查找404错误的具体原因。 4. **版本检查**:确保依赖库兼容,如数据库驱动、框架版本。 5. **测试和监控**:使用工具如Postman测试API端点,监控服务器状态。 6. **修复代码**:如果是应用特定问题,修复相关代码。 参考引用: - 从引用[1],可以借鉴:检查配置文件,确保相关servlet启用;考虑版本降级。 - 从引用[2],可以借鉴:确保驱动版本匹配。 但用户的问题是更一般的web页面404,所以我需要generalize。 回答结构: - 先用中文,结构清晰。 - 分为原因和解决方案。 - 添加引用标识,如[^1]。 - 生成相关问题。 最后,生成相关问题。 确保回答真实可靠:基于常见web开发知识。 最终输出: 1. 回答原因和解决方案。 2. 添加引用。 3. 生成相关问题。 </think>### HTTP Status 404 – Not Found错误的原因及解决方案 HTTP Status 404 – Not Found错误表示客户端请求的资源在服务器上无法找到。如果错误仅偶尔发生(即间歇性出现),这通常是由于临时性或动态因素导致的,而非永久性错误。以下我将从原因和解决方案两方面逐步分析,基于常见Web开发实践和参考引用内容[^1][^2],帮助您诊断和修复问题。核心思路是:先排查配置和依赖问题,再检查动态因素(如网络或负载)。 #### 一、常见原因分析 HTTP 404错误的根本原因是服务器无法定位请求的URL资源,但“偶尔”发生则暗示问题可能与环境变化或外部依赖相关。以下是主要可能原因: 1. **URL路径或资源变动问题**: - 请求的URL拼写错误、大小写敏感问题,或资源被临时移动/删除。 - 在动态Web应用中,某些页面可能仅在特定条件下加载(如用户会话有效时),如果会话过期或参数无效,会导致404错误间歇性出现[^1]。 2. **服务器或应用配置错误**: - 服务器配置文件(如Nginx/Apache的虚拟主机配置)错误,导致部分请求被错误路由。 - 应用框架(如Spring Boot)中的端点未启用或配置不正确。参考引用[1]提到,在Druid监控页面中,如果`stat-view-servlet.enabled`未设置为`true`,会引发404错误;类似地,其他Servlet或API端点如果未激活,也会造成间歇性失败[^1]。 - 负载均衡问题:在多服务器环境中,请求被分发到未部署资源的节点,导致偶发404。 3. **依赖版本兼容性问题**: - 库或驱动版本不匹配,引发资源加载失败。参考引用[2]强调,MySQL驱动与数据库版本必须严格一致,否则可能导致JDBC连接失败,进而触发404;这在更新依赖后可能间歇性出现[^2]。 - 框架版本冲突:如引用[1]中Druid版本过高(>1.1.10)导致监控页面不可用,类似问题可能在其他库中发生。 4. **网络或服务器临时问题**: - 网络抖动或DNS解析失败,使请求未到达正确服务器。 - 服务器高负载或重启期间,资源暂时不可访问。 - 缓存问题:浏览器或CDN缓存了过期的URL,导致重定向失败。 5. **部署和代码问题**: - 资源部署不完整(如静态文件未上传到服务器),或在热部署时出现间歇性错误。 - 应用代码逻辑缺陷:例如,某些请求路由仅在特定参数下有效,参数缺失时会失败。 #### 二、解决方案 针对“偶尔”发生的404错误,建议采用分层排查法:先检查配置和依赖,再监控动态因素。以下是具体步骤: 1. **验证URL和请求路径**: - 确保请求URL完全正确(包括大小写和路径分隔符)。使用浏览器开发者工具(Network标签)捕获失败请求的详细信息。 - 测试固定URL:选择一个稳定页面(如首页),多次访问以确认是否仅特定路径出错。如果是API,使用Postman模拟请求。 2. **检查和修复配置文件**: - **应用配置文件**:参考引用[1],在Spring Boot应用中,检查`application.yml`或`application.properties`: - 确保所有端点(如Servlet)已启用。例如,对于监控页面,添加类似配置: ```yaml stat-view-servlet: enabled: true # 必须设为true,否则可能报404 url-pattern: /druid/* login-username: your_username login-password: your_password ``` - 使用在线工具(如https://www.toyaml.com/)将YML转为Properties格式,避免语法错误[^1]。 - **服务器配置**:检查Web服务器(如Nginx/Tomcat)的配置: - 确认虚拟主机或上下文路径正确。 - 查看错误日志(如Tomcat的`catalina.out`),定位404请求的来源。 3. **解决依赖和版本问题**: - **版本降级或更新**:参考引用[1][^2],如果涉及特定库(如Druid),尝试降级版本: - 在Maven中,指定兼容版本(例如Druid 1.1.10): ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> <!-- 降级解决兼容问题 --> </dependency> ``` - 确保所有驱动版本匹配:如MySQL驱动需与数据库版本一致(参考引用[2])。 - **依赖检查**:运行`mvn dependency:tree`或等效命令,排查冲突库。 4. **监控和日志分析**: - 启用详细日志:在应用日志中增加404错误的跟踪(如Spring Boot的`logging.level.org.springframework.web=DEBUG`)。 - 服务器日志:查看Web服务器日志,分析404发生时的请求IP、时间戳和路径。 - 监控工具:使用Prometheus或ELK stack监控服务器负载和网络延迟,识别偶发错误规律。 5. **处理网络和部署问题**: - 网络诊断:使用`ping`或`traceroute`测试网络稳定性;确保DNS解析正确。 - 负载均衡:如果在集群环境,检查负载均衡器配置,确保请求均匀分发。 - 重新部署资源:清除浏览器缓存,或强制刷新CDN;确保静态资源完整上传。 6. **代码级修复**: - 代码审查:检查路由逻辑(如Spring的`@RequestMapping`),确保所有端点处理异常(添加`@ExceptionHandler`)。 - 测试:编写单元测试覆盖404场景,使用工具如JUnit或Selenium进行压力测试。 一般建议:从简单步骤开始(如配置检查),逐步深入。如果问题仅在特定用户或时段发生,重点排查会话或负载问题。参考引用[1][^2]表明,404错误常源于配置疏忽或版本不兼容,优先处理这些方面。 #### 三、预防措施 - **自动化测试**:集成CI/CD管道,每次部署前运行端到端测试。 - **版本管理**:使用依赖管理工具(如Maven BOM)锁定库版本。 - **监控告警**:配置Sentry或类似工具实时告警404错误。 通过以上步骤,您应能定位间歇性404错误的源头。如果问题未解决,提供更多上下文(如错误日志、框架名称),我可以进一步分析。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值