关于 http和[removed].href的分析 、URL中“#” “?” &“”号的作用和域名的区分

本文详细解析了URL的组成部分,包括协议、主机名、端口、路径、查询参数及锚点,并介绍了它们在浏览器和服务器交互中的作用。此外,还讨论了如何利用URL特性进行前端开发实践。

先分析一下,如何对一个完整的网址进行分析

例如:https://www.baidu.com:8080/aaa/2.html?id=10#name

window.location.href 可以拿到当前页面的地址,也就是上面给的地址例子

hostname(主机名): www.baidu.com  (域名)

port(端口): 8080  (端口号)

host: www.baidu.com:8080

pathname: /aaa/2.html

search: ?id=10

search是不包括hash值的

hash(锚点): #name

protocol(协议,草案): https  (协议)

 

可以通过window.location拿到所有的信息

然后根据hash的值来判断ajax的异步请求数据

(function(window){

   window.addEventListener('haschange',function(){

   var hash = window.location.hash;

   switch(hash){

   case '#index' :

    console.log('请求index');

  break;

   (以下内容省略了,和上面是一样的)

      .

      .

      .

  }

   });

   })()

 

hash(锚点)

window里面有个haschange事件,所以锚点的变化是可以拿到的

所以用 (function(window){

window.addEventListener('change',function(e){

  // 然后就可以根据锚点的值来判断ajax的异步请求数据   hash属于路径(url)的组成

})

})()

 

 

window.location.assign(url)和replace(url)区别

window.location.assign(url) : 加载URL 指定的新的 HTML 文档。就相当于一个链接,跳转到指定的url,当前页面会转为新页面内容,可以点击后退返回上一个页面。

      window.location.replace(url) : 通过加载 URL 指定的文档来替换当前文档 ,这个方法是替换当前窗口页面,前后两个页面共用一个窗口,所以是没有后退返回上一页的

 

阅读目录

1. #

 

    10年9月,twitter改版。一个显著变化,就是URL加入了"#!"符号。比如,改版前的用户主页网址为http://twitter.com/username改版后,就变成了http://twitter.com/#!/username
  这是主流网站第一次将"#"大规模用于重要URL中。这表明井号(Hash)的作用正在被重新认识。本文根据HttpWatch的文章,整理与井号有关的所有重要知识点。
一、#的涵义
  #代表网页中的一个位置。其右面的字符,就是该位置的标识符。比如,http://www.example.com/index.html#print就代表网页index.html的print位置。浏览器读取这个URL后,会自动将print位置滚动至可视区域。
  为网页位置指定标识符,有两个方法。一是使用锚点,比如<a name="print"></a>,二是使用id属性,比如<div id="print">。


二、HTTP请求不包括#
  #是用来指导浏览器动作的,对服务器端完全无用。所以,HTTP请求中不包括#。
比如,访问下面的网址,http://www.example.com/index.html#print,浏览器实际发出的请求是这样的:

GET /index.html HTTP/1.1
Host: www.example.com

 

三、#后的字符
  在第一个#后面出现的任何字符,都会被浏览器解读为位置标识符。这意味着,这些字符都不会被发送到服务器端。
比如,下面URL的原意是指定一个颜色值:http://www.example.com/?color=#fff,但是,浏览器实际发出的请求是:

GET /?color= HTTP/1.1
Host: www.example.com

   

四、改变#不触发网页重载
  单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页。
比如,从http://www.example.com/index.html#location1改成http://www.example.com/index.html#location2,浏览器不会重新向服务器请求index.html。

 

五、改变#会改变浏览器的访问历史
  每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用"后退"按钮,就可以回到上一个位置。这对于ajax应用程序特别有用,可以用不同的#值,表示不同的访问状态,然后向用户给出可以访问某个状态的链接。值得注意的是,上述规则对IE 6和IE 7不成立,它们不会因为#的改变而增加历史记录。
  

六、window.location.hash读取#值
  window.location.hash这个属性可读可写。读取时,可以用来判断网页状态是否改变;写入时,则会在不重载网页的前提下,创造一条访问历史记录。
  

七、onhashchange事件
  这是一个HTML 5新增的事件,当#值发生变化时,就会触发这个事件。IE8+、Firefox 3.6+、Chrome 5+、Safari 4.0+支持该事件。
  它的使用方法有三种:

  • window.onhashchange = func;
  • <body οnhashchange="func();">
  • window.addEventListener("hashchange", func, false);

  对于不支持onhashchange的浏览器,可以用setInterval监控location.hash的变化。

八、Google抓取#的机制
  默认情况下,Google的网络蜘蛛忽视URL的#部分。
  但是,Google还规定,如果你希望Ajax生成的内容被浏览引擎读取,那么URL中可以使用"#!",Google会自动将其后面的内容转成查询字符串_escaped_fragment_的值。
  比如,Google发现新版twitter的URL:http://twitter.com/#!/username
  就会自动抓取另一个URL:http://twitter.com/?_escaped_fragment_=/username
  通过这种机制,Google就可以索引动态的Ajax内容。

 

AJAX = 异步 JavaScriptXML标准通用标记语言的子集)。AJAX 是一种用于创建快速动态网页的技术。

回到顶部

2. ?

1)连接作用:比如

http://www.xxx.com/Show.asp?id=77&nameid=2905210001&page=1

2)清除缓存:比如

http://www.xxxxx.com/index.html 
http://www.xxxxx.com/index.html?test123123

两个url打开的页面一样,但是后面这个有问号,说明不调用缓存的内容,而认为是一个新地址,重新读取。

回到顶部

3. &

不同参数的间隔符

  

js清除浏览器缓存的几种方法

 

一、CSS和js为什么带参数(形如.css?t=与.js?t=)怎样获取代码

css和js带参数(形如.css?t=与.js?t=) 
使用参数有两种可能: 
第一、脚本并不存在,而是服务端动态生成的,因此带了个版本号,以示区别。 即上面代码对于文件来说 等价于 但浏览器会认为他是 该文件的某个版本! 
第二、客户端会缓存这些css或js文件,因此每次升级了js或css文件后,改变版本号,客户端浏览器就会重新下载新的js或css文件 ,刷性缓存的作用。 
第二种情况最多,也可能两种同时存在。 
版本号,可以是一个随机数,也可以是一个递增的值,大版本小版本的方式,或者根据脚本的生成时间书写,比如就是精确到了生成脚本的秒,而 2.3.3 就是大版本小版本的方式。

二、关于浏览器缓存

浏览器缓存,有时候我们需要他,因为他可以提高网站性能和浏览器速度,提高网站性能。但是有时候我们又不得不清除缓存,因为缓存可能误事,出现一些错误的数据。像股票类网站实时更新等,这样的网站是不要缓存的,像有的网站很少更新,有缓存还是比较好的。今天主要介绍清除缓存的几种方法。

清理网站缓存的几种方法

meta方法

<META HTTP-EQUIV="pragma" CONTENT="no-cache"> 
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate"> 
<META HTTP-EQUIV="expires" CONTENT="0">

清理form表单的临时缓存 
方式一:用ajax请求服务器最新文件,并加上请求头If-Modified-Since和Cache-Control,如下:

 $.ajax({
     url:'www.haorooms.com',
     dataType:'json',
     data:{},
     beforeSend :function(xmlHttp){ 
        xmlHttp.setRequestHeader("If-Modified-Since","0"); 
        xmlHttp.setRequestHeader("Cache-Control","no-cache");
     },
     success:function(response){
         //操作
     }
     async:false
  });

方法二,直接用cache:false,

 $.ajax({
     url:'www.haorooms.com',
     dataType:'json',
     data:{},
     cache:false, 
     ifModified :true ,

     success:function(response){
         //操作
     }
     async:false
  });

方法三:用随机数,随机数也是避免缓存的一种很不错的方法!

URL 参数后加上 "?ran=" + Math.random(); //当然这里参数 ran可以任意取了
eg:
<script> 
document.write("<s"+"cript type='text/javascript' src='/js/test.js?"+Math.random()+"'></scr"+"ipt>"); 
</script>

其他的类似,只需在地址后加上+Math.random() 
注意:因为Math.random() 只能在Javascript 下起作用,故只能通过Javascript的调用才可以 

方法四:用随机时间,和随机数一样。

在 URL 参数后加上 "?timestamp=" + new Date().getTime(); 

PHP后端清理

在服务端加 header("Cache-Control: no-cache, must-revalidate");等等(如php中)

方法五:

5、window.location.replace("WebForm1.aspx");   
参数就是你要覆盖的页面,replace的原理就是用当前页面替换掉replace参数指定的页面。   
这样可以防止用户点击back键。使用的是javascript脚本,举例如下: 
a.html 
以下是引用片段: 
<html> 
     <head> 
         <title>a</title>      
         <script language="javascript"> 
             function jump(){ 
                 window.location.replace("b.html"); 
             } 
         </script> 
     </head> 
     <body> 
        <a href="javascript:jump()">b</a> 
    </body> 
</html>  

b.html 
以下是引用片段: 
<html> 
     <head> 
         <title>b</title>      
         <script language="javascript"> 
             function jump(){ 
                 window.location.replace("a.html"); 
             } 
         </script> 
     </head> 
     <body> 
        <a href="javascript:jump()">a</a> 
    </body> 
</html>  

顶级域名、一级域名、二级域名、三级域名的区别

顶级域名,我们知道域名由两个或两个以上的词构成,中间由点号分隔开,最右边的那个词就叫做顶级域名。我们接触的顶级域名又分为两类:一是国家和地区顶级域名。例如中国是cn,美国是us等;二是国际顶级域名,例如表示工商企业的.com,表示非盈利组织的.org,表示网络商的.net等。 
一级域名又称顶级域名,即: 
baidu.com 
二级域名,即: 
www.baidu.com 
另外 .baidu.com也属于二级域名,上可以填写任意内容,都属于二级域名。 
三级域名,也就是二级域名的子目录,即: 
..baidu.com ,_上可以填写任意内容,都属于三级域名。 
一个完整的域名一般由二个或二个以上部分组成,各部分之间用英文的句号”.”来分隔,最后一个”.”的右边部分称为顶级域名(TLD,也称为一级域名),一级域名”.”的左边部分称为二级域名(SLD),二级域名的左边部分称为三级域名,以此类推,每一级的域名控制它下一级域名的分配。三级域名是形如”().().baidu.com”的域名,可以当做是二级域名的子域名,特征为域名包含两个”.”,一般来说,三级域名都是免费的。

[root@yfw ~]# cd /opt/openfire [root@yfw openfire]# # 查看完整的 openfire.log,从最近一次重启开始 [root@yfw openfire]# tail -n 200 /opt/openfire/logs/openfire.log | grep -A 20 -B 5 &quot;Plugin &#39;restapi&#39; was removed&quot; at java.lang.Thread.run(Thread.java:829) [?:?] 2025.10.03 04:07:24.817 INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - Plugin &#39;restapi&#39; was removed from the file system. 2025.10.03 04:07:24.817 ERROR [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - An unexpected exception occurred: java.lang.NullPointerException: null at org.jivesoftware.openfire.container.PluginManager.unloadPlugin(PluginManager.java:883) ~[xmppserver-4.9.2.jar:4.9.2] at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.run(PluginMonitor.java:305) [xmppserver-4.9.2.jar:4.9.2] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?] at java.lang.Thread.run(Thread.java:829) [?:?] 2025.10.03 04:07:44.818 INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - Plugin &#39;restapi&#39; was removed from the file system. 2025.10.03 04:07:44.819 ERROR [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - An unexpected exception occurred: java.lang.NullPointerException: null at org.jivesoftware.openfire.container.PluginManager.unloadPlugin(PluginManager.java:883) ~[xmppserver-4.9.2.jar:4.9.2] at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.run(PluginMonitor.java:305) [xmppserver-4.9.2.jar:4.9.2] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?] at java.lang.Thread.run(Thread.java:829) [?:?] 2025.10.03 04:08:04.820 INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - Plugin &#39;restapi&#39; was removed from the file system. 2025.10.03 04:08:04.820 ERROR [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - An unexpected exception occurred: java.lang.NullPointerException: null at org.jivesoftware.openfire.container.PluginManager.unloadPlugin(PluginManager.java:883) ~[xmppserver-4.9.2.jar:4.9.2] at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.run(PluginMonitor.java:305) [xmppserver-4.9.2.jar:4.9.2] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?] at java.lang.Thread.run(Thread.java:829) [?:?] 2025.10.03 04:08:24.821 INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - Plugin &#39;restapi&#39; was removed from the file system. 2025.10.03 04:08:24.821 ERROR [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - An unexpected exception occurred: java.lang.NullPointerException: null at org.jivesoftware.openfire.container.PluginManager.unloadPlugin(PluginManager.java:883) ~[xmppserver-4.9.2.jar:4.9.2] at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.run(PluginMonitor.java:305) [xmppserver-4.9.2.jar:4.9.2] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?] at java.lang.Thread.run(Thread.java:829) [?:?] 2025.10.03 04:08:44.823 INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - Plugin &#39;restapi&#39; was removed from the file system. 2025.10.03 04:08:44.823 ERROR [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - An unexpected exception occurred: java.lang.NullPointerException: null at org.jivesoftware.openfire.container.PluginManager.unloadPlugin(PluginManager.java:883) ~[xmppserver-4.9.2.jar:4.9.2] at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.run(PluginMonitor.java:305) [xmppserver-4.9.2.jar:4.9.2] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?] at java.lang.Thread.run(Thread.java:829) [?:?] 2025.10.03 04:09:04.824 INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - Plugin &#39;restapi&#39; was removed from the file system. 2025.10.03 04:09:04.824 ERROR [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - An unexpected exception occurred: java.lang.NullPointerException: null at org.jivesoftware.openfire.container.PluginManager.unloadPlugin(PluginManager.java:883) ~[xmppserver-4.9.2.jar:4.9.2] at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.run(PluginMonitor.java:305) [xmppserver-4.9.2.jar:4.9.2] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?] at java.lang.Thread.run(Thread.java:829) [?:?] 2025.10.03 04:09:24.825 INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - Plugin &#39;restapi&#39; was removed from the file system. 2025.10.03 04:09:24.826 ERROR [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - An unexpected exception occurred: java.lang.NullPointerException: null at org.jivesoftware.openfire.container.PluginManager.unloadPlugin(PluginManager.java:883) ~[xmppserver-4.9.2.jar:4.9.2] at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.run(PluginMonitor.java:305) [xmppserver-4.9.2.jar:4.9.2] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?] at java.lang.Thread.run(Thread.java:829) [?:?] 2025.10.03 04:09:44.560 INFO [Thread-2]: org.jivesoftware.openfire.XMPPServer - Shutting down plugins ... 2025.10.03 04:09:44.560 INFO [Thread-2]: org.jivesoftware.openfire.container.PluginManager - Shutting down. Unloading all loaded plugins... 2025.10.03 04:09:44.562 INFO [Thread-2]: org.jivesoftware.openfire.XMPPServer - Shutting down 54 modules ... 2025.10.03 04:09:44.735 INFO [shutdown-thread-0]: org.jivesoftware.openfire.pubsub.DefaultPubSubPersistenceProvider - Flushing write cache to database 2025.10.03 04:09:44.738 INFO [shutdown-thread-0]: org.jivesoftware.openfire.OfflineMessageStore - Offline message cleaning - Stop old timer if started 2025.10.03 04:09:44.748 INFO [Thread-2]: org.jivesoftware.openfire.XMPPServer - Openfire stopped 2025.10.03 04:09:46.319 INFO [main]: org.jivesoftware.openfire.XMPPServer - Registering shutdown hook (standalone mode) 2025.10.03 04:09:46.861 INFO [main]: org.jivesoftware.util.cache.ConsistencyMonitor - Applying configuration for cache consistency check. Enabled: false 2025.10.03 04:09:46.874 INFO [main]: org.jivesoftware.util.cache.CacheFactory - Created cache [org.jivesoftware.util.cache.DefaultLocalCacheStrategy] for Routing Servers Cache 2025.10.03 04:09:46.875 INFO [main]: org.jivesoftware.util.cache.CacheFactory - Created cache [org.jivesoftware.util.cache.DefaultLocalCacheStrategy] for Routing Components Cache -- 2025.10.03 04:09:47.476 INFO [main]: org.jivesoftware.openfire.muc.spi.MultiUserChatServiceImpl - Rescheduling user idle task, recurring every PT15M 2025.10.03 04:09:47.480 INFO [main]: org.jivesoftware.openfire.muc.spi.MultiUserChatServiceImpl - 多用户聊天域:conference.localhost 2025.10.03 04:09:47.491 INFO [main]: org.jivesoftware.openfire.muc.spi.MultiUserChatServiceImpl - Rescheduling user idle task, recurring every PT15M 2025.10.03 04:09:47.492 INFO [main]: org.jivesoftware.openfire.muc.spi.MultiUserChatServiceImpl - 多用户聊天域:lobby.localhost 2025.10.03 04:09:47.508 INFO [main]: org.jivesoftware.openfire.XMPPServer - Openfire 4.9.2 [2025年10月3日 上午4:09:47] 2025.10.03 04:09:47.516 INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - Plugin &#39;restapi&#39; was removed from the file system. 2025.10.03 04:09:47.517 ERROR [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - An unexpected exception occurred: java.lang.NullPointerException: null at org.jivesoftware.openfire.container.PluginManager.unloadPlugin(PluginManager.java:883) ~[xmppserver-4.9.2.jar:4.9.2] at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.run(PluginMonitor.java:305) [xmppserver-4.9.2.jar:4.9.2] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?] at java.lang.Thread.run(Thread.java:829) [?:?] 2025.10.03 04:09:47.760 INFO [main]: org.jivesoftware.util.cache.CacheFactory - Created cache [org.jivesoftware.util.cache.DefaultLocalCacheStrategy] for LDAP UserDN 2025.10.03 04:09:48.181 INFO [main]: org.jivesoftware.openfire.net.SASLAuthentication - Support added for the &#39;ANONYMOUS&#39; SASL mechanism. 2025.10.03 04:09:48.181 INFO [main]: org.jivesoftware.openfire.net.SASLAuthentication - Support added for the &#39;CRAM-MD5&#39; SASL mechanism. 2025.10.03 04:09:48.181 INFO [main]: org.jivesoftware.openfire.net.SASLAuthentication - Support added for the &#39;DIGEST-MD5&#39; SASL mechanism. 2025.10.03 04:09:48.181 INFO [main]: org.jivesoftware.openfire.net.SASLAuthentication - Support added for the &#39;EXTERNAL&#39; SASL mechanism. 2025.10.03 04:09:48.182 INFO [main]: org.jivesoftware.openfire.net.SASLAuthentication - Support added for the &#39;GSSAPI&#39; SASL mechanism. 2025.10.03 04:09:48.182 INFO [main]: org.jivesoftware.openfire.net.SASLAuthentication - Support added for the &#39;JIVE-SHAREDSECRET&#39; SASL mechanism. 2025.10.03 04:09:48.182 INFO [main]: org.jivesoftware.openfire.net.SASLAuthentication - Support added for the &#39;PLAIN&#39; SASL mechanism. 2025.10.03 04:09:48.182 INFO [main]: org.jivesoftware.openfire.net.SASLAuthentication - Support added for the &#39;SCRAM-SHA-1&#39; SASL mechanism. 2025.10.03 04:09:48.220 INFO [main]: org.jivesoftware.util.cache.CacheFactory - Created cache [org.jivesoftware.util.cache.DefaultLocalCacheStrategy] for Remote Server Configurations 2025.10.03 04:10:07.552 INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - Plugin &#39;restapi&#39; was removed from the file system. 2025.10.03 04:10:07.552 ERROR [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - An unexpected exception occurred: java.lang.NullPointerException: null at org.jivesoftware.openfire.container.PluginManager.unloadPlugin(PluginManager.java:883) ~[xmppserver-4.9.2.jar:4.9.2] at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.run(PluginMonitor.java:305) [xmppserver-4.9.2.jar:4.9.2] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?] at java.lang.Thread.run(Thread.java:829) [?:?] 2025.10.03 04:10:27.554 INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - Plugin &#39;restapi&#39; was removed from the file system. 2025.10.03 04:10:27.555 ERROR [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - An unexpected exception occurred: java.lang.NullPointerException: null at org.jivesoftware.openfire.container.PluginManager.unloadPlugin(PluginManager.java:883) ~[xmppserver-4.9.2.jar:4.9.2] at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.run(PluginMonitor.java:305) [xmppserver-4.9.2.jar:4.9.2] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?] at java.lang.Thread.run(Thread.java:829) [?:?] 2025.10.03 04:10:47.556 INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - Plugin &#39;restapi&#39; was removed from the file system. 2025.10.03 04:10:47.556 ERROR [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - An unexpected exception occurred: java.lang.NullPointerException: null at org.jivesoftware.openfire.container.PluginManager.unloadPlugin(PluginManager.java:883) ~[xmppserver-4.9.2.jar:4.9.2] at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.run(PluginMonitor.java:305) [xmppserver-4.9.2.jar:4.9.2] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?] at java.lang.Thread.run(Thread.java:829) [?:?] 2025.10.03 04:11:07.557 INFO [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - Plugin &#39;restapi&#39; was removed from the file system. 2025.10.03 04:11:07.558 ERROR [PluginMonitorTask-2]: org.jivesoftware.openfire.container.PluginMonitor - An unexpected exception occurred: java.lang.NullPointerException: null at org.jivesoftware.openfire.container.PluginManager.unloadPlugin(PluginManager.java:883) ~[xmppserver-4.9.2.jar:4.9.2] at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.run(PluginMonitor.java:305) [xmppserver-4.9.2.jar:4.9.2] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?] at java.lang.Thread.run(Thread.java:829) [?:?] [root@yfw openfire]#
最新发布
10-04
你已经取得了非常关键的进展! 现在我们终于看到了 **真正的错误日志**: ```log ERROR [PluginMonitorTask-2]: An unexpected exception occurred: java.lang.NullPointerException: null at org.jivesoftware.openfire.container.PluginManager.unloadPlugin(PluginManager.java:883) ~[xmppserver-4.9.2.jar:4.9.2] at org.jivesoftware.openfire.container.PluginMonitor$MonitorTask.run(PluginMonitor.java:305) ``` --- ## 🔍 深度分析:`NullPointerException` 在 `PluginManager.java:883` 这是 Openfire 内部的一个 **bug 或边界条件处理缺失**。 让我们来理解发生了什么。 ### 📌 日志关键线索 1. `Plugin &#39;restapi&#39; was removed from the file system.` &rarr; 这是误导性信息。它不是&ldquo;被删除&rdquo;,而是 **载失败后被卸载** 2. 然后调用 `unloadPlugin(...)` 方法 3. 抛出 `NullPointerException` 在第 883 行: ```java if (plugin.isActive()) { plugin.destroyPlugin(); } ``` 👉 说明:`plugin` 对象为 `null`,但代码没有判空就直接调用 `.isActive()` --- ## ✅ 根本原因:插件载失败 &rarr; 导致 `plugin` 实例为 `null` &rarr; 卸载时报 NPE 也就是说: &gt; ❌ 插件在 `initializePlugin` 前就已经载失败了(比如类找不到、签名不对、包结构问题等) &gt; ➡️ Openfire 创建 `plugin` 实例失败 &rarr; `plugin = null` &gt; ➡️ 后续尝试卸载时触发 `null.isActive()` &rarr; `NPE` 所以我们要找的是:**为什么插件载失败?** --- ## ✅ 关键排查点:目录结构 &amp; 类路径 你现在使用的是 **目录结构插件**: ``` /opt/openfire/plugins/restapi/ ├── plugin.xml └── classes/ └── RestApiPlugin.class ``` 这种结构要求: - `RestApiPlugin.class` 必须在默认包中(无 package) - 文件必须可读 - Openfire 能成功通过反射创建实例 但我们怀疑:**Openfire 尝试载类失败 &rarr; 返回 null &rarr; 导致后续 NPE** --- ## ✅ 解决方案:改用 `.jar` 插件格式(推荐标准方式) Openfire 官方插件几乎全是 `.jar` 包形式,且更稳定。 ### ✅ 步骤 1:打包成 `restapi.jar` ```bash # 创建临时目录 mkdir -p ~/openfire-plugin-build cd ~/openfire-plugin-build # 创建 classes 目录并复制你的 class mkdir -p classes cp /opt/openfire/plugins/restapi/classes/RestApiPlugin.class classes/ # 打包成 jar jar cf restapi.jar -C classes . ``` ✅ 输出:`restapi.jar` --- ### ✅ 步骤 2:部署 `.jar` 插件 ```bash # 删除旧的目录结构插件 rm -rf /opt/openfire/plugins/restapi rm -rf /opt/openfire/work/plugins/restapi* # 创建新插件目录 mkdir -p /opt/openfire/plugins/restapi # 复制 JAR 文件 cp restapi.jar /opt/openfire/plugins/restapi/ # 写入 plugin.xml(同前) cat &gt; /opt/openfire/plugins/restapi/plugin.xml &lt;&lt; &#39;EOF&#39; &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt; &lt;plugin&gt; &lt;className&gt;RestApiPlugin&lt;/className&gt; &lt;name&gt;REST API Plugin&lt;/name&gt; &lt;description&gt;Simple REST API Plugin&lt;/description&gt; &lt;author&gt;Admin&lt;/author&gt; &lt;version&gt;1.0.0&lt;/version&gt; &lt;date&gt;2025-10-03&lt;/date&gt; &lt;minServerVersion&gt;4.0.0&lt;/minServerVersion&gt; &lt;/plugin&gt; EOF # 设置权限 chown -R openfire:openfire /opt/openfire/plugins/restapi chmod -R 755 /opt/openfire/plugins/restapi ``` 📌 注意: - 不需要 `classes/` 目录 - 只要有 `restapi.jar` `plugin.xml` 即可 --- ### ✅ 步骤 3:重启并查看完整日志 ```bash systemctl restart openfire # 查看完整日志(不要 grep) tail -f /opt/openfire/logs/openfire.log ``` 等待几秒,观察是否出现: ``` INFO [PluginMonitorTask-2] Loading plugin: restapi 🎉 REST API Plugin 已成功载! INFO [PluginManager] Successfully loaded plugin: restapi ``` 或者是否有更详细的异常信息,如: ``` Caused by: java.lang.ClassNotFoundException: RestApiPlugin ``` --- ##强诊断:添打印语句验证类载 修改 `RestApiPlugin.java`: ```java public class RestApiPlugin implements org.jivesoftware.openfire.container.Plugin { static { System.out.println(&quot;🔧 静态块执行:RestApiPlugin 类已载!&quot;); } public RestApiPlugin() { System.out.println(&quot;🆕 RestApiPlugin 构造函数被调用&quot;); } @Override public void initializePlugin(org.jivesoftware.openfire.container.PluginManager manager, java.io.File pluginDirectory) { System.out.println(&quot;🎉 插件已初始化!目录: &quot; + pluginDirectory.getAbsolutePath()); } @Override public void destroyPlugin() { System.out.println(&quot;🔌 插件已销毁&quot;); } } ``` 重新编译、打包、部署,看哪一行输出了。 👉 如果连&ldquo;静态块&rdquo;都没打印,说明类根本没被载。 --- ## ✅ 其他可能的问题检查清单 | 检查项 | 命令 / 方法 | |------|-----------| | ✅ Java 版本兼容性 | `java -version`(Openfire 4.9.2 推荐 JDK 11) | | ✅ 类文件是否损坏 | `javap -cp restapi.jar RestApiPlugin` | | ✅ 是否有 `package` 声明? | 确保源码中没有 `package xxx;` | | ✅ 权限是否正确 | `ls -l /opt/openfire/plugins/restapi/` 应为 `openfire:openfire` | | ✅ work 缓存干扰 | 删除 `/opt/openfire/work/plugins/restapi*` | --- ## ✅ 验证类是否存在且无 package 运行: ```bash jar -xf restapi.jar javap RestApiPlugin | head -10 ``` 输出应类似: ``` Compiled from &quot;RestApiPlugin.java&quot; public class RestApiPlugin implements org.jivesoftware.openfire.container.Plugin ``` 而不是: ``` public class com.example.RestApiPlugin ... ``` --- ## ✅ 成功标志 当看到以下日志时,表示插件真正载成功: ``` INFO [PluginMonitorTask-2] Loading plugin: restapi 🔧 静态块执行:RestApiPlugin 类已载! 🆕 RestApiPlugin 构造函数被调用 🎉 插件已初始化!目录: /opt/openfire/plugins/restapi INFO [PluginManager] Successfully loaded plugin: restapi ``` --- ## 🧩 总结:当前状态与下一步 | 状态 | 结论 | |------|------| | ✅ 编译正确 | 使用了 `container.Plugin` 接口 | | ⚠️ 载失败 | Openfire 未能创建 `plugin` 实例 | | 💥 卸载时报 NPE | 因 `plugin == null`,是结果而非原因 | | ✅ 下一步 | 改用 `.jar` 插件 + 添诊断输出 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值