1. 什麼是Referer?
Referer 是 HTTP
請求(requset) header 的一部分,當瀏覽器(或者模擬瀏覽器行爲)向web 服務器發送請求的時候,頭信息裏就有包含 Referer 。
比如我在www.csdn.net
裏點擊一篇博客,那麼點擊這個博客,它的header信息裏就有:
Referer=https://www.csdn.net/
如下圖:request header有這麼一行(從瀏覽器的開發者工具->NetWork->Header中看)
簡單來說:Referer就是當前頁面的上一頁面
那麼就可以根據Referer來判斷你的頁面是不是被盜取了,被另外一方的網站引用了。
小彩蛋:Referer是Referrer的錯誤拼寫,但HTTP/1.0 協議
當時拼錯了發現晚了,已經被大量使用,如果要改過來需要所有服務端、客戶端的一致配合,還有大量的代碼需要排查修改。於是,HTTP
的標準制定者們決定將錯就錯,不改了。到今日,搜索Referer這個單詞,發現解釋也是跟Referrer一樣的解釋了,廣爲流傳變成正確的了。
2. 爲什麼使用Referer?
防盜鏈
舉個例子:
一個正版網站:www.163.com
;其中有個頁面是www.163.com/new.html
一個盜版網站:www.361.com
;其中有個頁面是www.361.com/new361.html
而盜版網站的鏈接有的是偷取的正版網站的鏈接,據爲己有,這時候如果設置了防盜鏈就會被攔截,轉到服務器想讓它到的地方。
如圖:
3. 什麼是空Referer?
3.1 空Referer的定義(Referer="" || Referer=null):
- Referer 的內容爲空;
- 一個
HTTP
請求中根本不包含 Referer 。
3.2 什麼時候 HTTP
請求會不包含 Referer 字段呢?
Referer 代表的是上一個頁面(請求地址),如果上一個請求地址是沒有的,那麼Referer 自然也是空的。
3.3 那麼如何辦到上一個頁面是空的呢?
直接在瀏覽器的地址欄中輸入一個資源的URL地址,這種方式的請求是不包含Referer的 ,這是一個“憑空產生”的 HTTP
請求,並不是從一個地方鏈接過去的。
3.4 允許空Referer和不允許空Referer有什麼區別?
- 允許 Referer 爲空,意味着你允許瀏覽器或者重定向直接URL訪問資源。
- 不允許爲空,那麼直接輸入URL訪問會被攔截。
4. 如何使用Referer?
情景模擬:(本例子在tomcat9環境下,低版本亂碼請看本人另一篇博客解決:Servlet亂碼解決)
4.1 建立一個山寨網站,盜取鏈接:
1.在d盤建立一個文件夾shanzhai(名字隨意),再建立一個ROOT文件夾(一定大寫),再其中寫一個山寨網頁
2.山寨內容(注意我的tomcat端口是8081,默認8080)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我是山寨網站www.361.com</title>
</head>
<body>
<h1>我是山寨網站www.361.com</h1>
<hr />
<p>我是廣告1</p>
<a href="http://localhost:8081/RefererServlet">武漢加油!中國加油!</a>
<p>我是廣告2</p>
</body>
</html>
3.給山寨網站取一個域名www.361.com,到tomcat目錄下/conf/server.xml中Engine標籤內添加
<Host name="www.361.com" appBase="D:\shanzhai" />
4.到C:\Windows\System32\drivers\etc中修改hosts文件,在其末尾添加(代表訪問www.361.com還是在訪問本機哦)
127.0.0.1 www.361.com
4.2 建立一個web服務:一個Servlet和兩個頁面(Servlet3.0環境下)
1.web項目添加Servlet:RefererServlet(這個就是防盜鏈的控制器)
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/RefererServlet")
public class RefererServlet extends HttpServlet {
private static final long serialVersionUID = 7883076061572095135L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//獲取HTTP header中的Referer
String referer=request.getHeader("Referer");
//判斷Referer是否符合標準:不允許直接URL訪問;不允許除了前綴http://localhost:8081的其他頁面訪問
//我的tomcat的端口是8081,默認8080
if (referer==null || "".equals(referer)|| !referer.startsWith("http://localhost:8081")){
//不符合標準的送去官網
response.sendRedirect("QQnews.html");
return;//退出Servlet
}
//符合標準進入鏈接頁面
request.getRequestDispatcher("chinaNO1.html").forward(request,response);
}
}
2.web項目添加正版網站頁面和新聞內容頁面
正版網站:騰訊新聞
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>騰訊新聞</title>
</head>
<body>
<h1>騰訊新聞</h1>
<hr />
<p>我是廣告1</p>
<a href="RefererServlet">武漢加油!中國加油!</a>
<p>我是廣告2</p>
</body>
</html>
中國加油頁面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>武漢加油!中國加油!</title>
</head>
<body>
<center>
<h1>武漢加油!中國加油!</h1>
<hr />
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1586511481911&di=ef37659dc6514450199730b2668aa0e5&imgtype=0&src=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fimages%2F20200226%2F0f8382216d03487bb5aaf787e8ef8e51.jpeg" />
<p>武漢加油,中國加油!</p>
<p>天佑中華,衆志成城,共渡難關!<br />
風雨過後一定有彩虹!武漢加油!中國加油!災難我們一起面對,一起承受!<br />
一定能打贏這場沒有硝煙的戰爭!
</p>
</center>
</body>
</html>
4.3 開始測試(啓動web服務)
1.打開盜版網站www.361.com:8081/ShanZhai.html (注意端口號和大寫)
2.訪問武漢加油,發現跳轉到正版新聞主頁了,防盜鏈判斷無法通行,攔截並跳轉,發揮作用!
3.在主頁訪問武漢加油,防盜鏈判斷可以通行
5.總結:
Referer是Http Header中的一個字段,它代表是的上一次的請求鏈接,我們在Servlet控制器中可以對其進行判斷,使用startsWith()方法限制Referer必須由本項目(域名)才能直接訪問所屬頁面,其他請求將被跳轉到你指定的頁面。
Referer爲空代表:直接URL輸入網址請求資源或者重定向請求資源等等(等讀者自行發掘哦)
Referer防盜鏈只能防止基礎的偷取頁面鏈接,並不是萬能的,通過java可以僞造HTTP請求,繼而仍能成功盜鏈。
本文參考:
javaweb之request獲取referer請求頭實現防盜鏈
ServletRequest實現的防盜鏈問題
什麼是Referer?Referer的作用?空Referer是怎麼回事?
如果對小夥伴們有所幫助,歡迎點贊評論支持作者的創作熱情~