Restful 提倡將接口的行為狀態放到了 Http 的頭部 method 里。對同一個資源的不同操作,接口 URL 可能是一樣的。行為規約主要有下面幾項:GET查詢資源,不會對資源產生變化的都用 GET。例:查詢慕課網 http Wiki 教程的所有小節列表:GET http://www.xianlaiwan.cn/http如果資源查詢的過程需要帶過濾參數,建議使用 URL 參數的形式:例:查詢慕課網 http 小節中作者是 rj 的文章GET http://www.xianlaiwan.cn/http?author=rj例:查詢慕課網 http 里面 id = 1 的文章GET http://www.xianlaiwan.cn/http/1POST新增某個資源:POST http://www.xianlaiwan.cn/http具體的參數放請求體中{"title":"restful","author":"rj","content":"xxxxxx"}PUT資源的修改:PUT http://www.xianlaiwan.cn/http/{articleId}具體的參數放請求體中{"title":"restful","author":"rj","content":"xxxxxx"}PATCHPATCH http://www.xianlaiwan.cn/http/{articleId}patch 跟 put 都是修改的意思,put 類型的修改請求體中需要包含全量的對象信息,而 patch 只需要帶上要修改的某幾個對象即可,沒有帶上的參數就代表不更新,采用原來的值。具體的參數放請求體中{"title":"aaa"}DELETE刪除資源:DELETE http://www.xianlaiwan.cn/http/{articleId}
spring-mvc.xml 用來配置與 Spring MVC 相關的組件信息,用來提供給 web 上下文對象進行組件維護。這些組件包括 Spring MVC 核心組件和用戶控制器組件。<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 啟動注解支持 --> <mvc:annotation-driven/> <!--靜態資源交給 tomcat default servelt 處理--> <mvc:default-servlet-handler /> <!--掃描組件位置--> <context:component-scan base-package="com.mk.web.action"></context:component-scan> <!-- 視圖解析器 --> <mvc:view-resolvers> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/jsp"></property> <property name="suffix" value=".jsp"></property> </bean> </mvc:view-resolvers></beans>元素解釋說明:mvc:annotation-driven: 啟動注解支持,完全使用 XML 進行 Spring MVC 項目維護,并不是很方便。即使在使用 XML 時,建議還是結合注解一起使用,這也是 Spring MVC 官方建議的;context:component-scan: 指定哪些組件由 Spring MVC 的上下文對象負責。除了 Spring MVC 內部組件外,再就是用戶控制器;mvc:view-resolvers: 配置具體的視圖解析器。Tips: 映射器、適配器等組件可以不用顯示配置,采用 Spring MVC 默認配置即可。
我們打開 ip_hash 指令的注釋,這個時候默認是使用客戶端的 ip 地址作為 hash 的 key,然后重啟 Nginx 服務并進行如下的命令行操作:# 使用本機的ip地址,無論請求多少出,通過hash轉發到的上游服務器地址都是一致的[shen@shen ~]$ curl http://180.76.152.1138002, server[shen@shen ~]$ curl http://180.76.152.1138002, server[shen@shen ~]$ curl http://180.76.152.1138002, server# 只有換了ip之后,請求轉發的上游地址才可能有變化[shen@shen ~]$ curl -H 'X-Forwarded-For: 111.10.1.3' http://180.76.152.1138000, server[shen@shen ~]$ curl -H 'X-Forwarded-For: 111.10.2.3' http://180.76.152.1138001, server
本節編寫一個 Flask 程序 request-url.py,打印 request 中和 URL 相關的屬性:from flask import Flaskfrom flask import requestapp = Flask(__name__)def echo(key, value): print('%-10s = %s' % (key, value))@app.route('/query')def query(): echo('url', request.url) echo('base_url', request.base_url) echo('host', request.host) echo('host_url', request.host_url) echo('path', request.path) echo('full_path', request.full_path) return 'hello'if __name__ == '__main__': app.run(port = 80)在瀏覽器中輸入 http://localhost/query?userId=123,程序在終端輸出如下:url = http://localhost/query?userId=123base_url = http://localhost/queryhost = localhosthost_url = http://localhost/path = /queryfull_path = /query?userId=123
Https 是一種通過計算機網絡進行安全通信的傳輸協議,經由 Http 進行通信,利用 SSL/TLS 建立安全信道,加密數據包。Https 使用的主要目的是提供對網站服務器的身份認證,同時保護交換數據的隱私與完整性。Http 服務的默認端口是 80,Https 服務的默認端口是 443。HTTP + SSL = HTTPS = HTTP + 身份認證 + 數據私密 + 數據完整性
本節中介紹了 Nginx 的四層反向代理和七層反向代理,并用案例進行了演示。剛開始使用時只是用了 http 指令塊,因為是針對 http 請求進行處理。這進行的是四層反向代理。nginx 七層方向代理處理的是 http 請求,對應的是 http 協議。如果只是轉發 http 請求,可以簡單使用 proxy_pass 指令即可。這和我們之前簡單的反向代理示例一致。
超鏈接是文章的資源向導,包括錨點連接和外部連接,可以幫助讀者快速定位到文章內的某個位置,或者打開外部的某個資源和網頁。常見的頁內錨點超鏈接如文檔目錄等。實例 5:一個屬于自己的門戶頁。#### 一個簡單的個人門戶- 常用網站 [百度](http://www.baidu.com), [慕課](http://www.xianlaiwan.cn), [Github](http://www.github.com)- 新聞 [人民網](http://www.people.com.cn/), [央視網](http://www.cctv.com/), [光明網](http://www.gmw.cn/),- 購物網站 [淘寶](http://www.taobao.com), [京東](http://www.jd.com)- 程序文檔 [小程序開發文檔](https://developers.weixin.qq.com/miniprogram/dev/framework/)渲染結果如下:
由于不同品牌的手機,USB 驅動程序也是不同的,所以推薦大家從品牌廠商的官網下載 USB 驅動程序。設備制造商驅動程序網址宏碁http://www.acer.com/worldwide/support/華碩https://www.asus.com/support/Download-Center/BlackBerryhttps://swdownloads.blackberry.com/Downloads/entry.do?code=4EE0932F46276313B51570F46266A608Dellhttp://support.dell.com/support/downloads/index.aspx?c=us&cs=19&l=en&s=dhs&~ck=anavmlFujitsuhttp://www.fmworld.net/product/phone/sp/android/develop/HTChttp://www.htc.com/support華為http://consumer.huawei.com/en/support/index.htmIntelhttp://www.intel.com/software/androidKyocerahttp://www.kyocera-wireless.com/support/phone_drivers.htm聯想http://support.lenovo.com/us/en/GlobalProductSelectorLGEhttp://www.lg.com/us/support/software-firmwareMotorolahttps://motorola-global-portal.custhelp.com/app/answers/detail/a_id/88481/MTKhttp://online.mediatek.com/Public Documents/MTK_Android_USB_Driver.zipSamsunghttp://developer.samsung.com/galaxy/others/android-usb-driver-for-windows夏普http://k-tai.sharp.co.jp/support/Sonyhttp://developer.sonymobile.com/downloads/drivers/小米http://www.xiaomi.com/c/driver/index.html中興http://support.zte.com.cn/support/news/NewsDetail.aspx?newsId=1000442
在 nginx.conf 中添加如下的 http 指令塊:http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; sendfile on; keepalive_timeout 65; gzip on; server { listen 8000; return 200 '8000, server\n'; } server { listen 8001; return 200 '8001, server\n'; } server { listen 8002; return 200 '8002, server\n'; } upstream backends { # ip_hash # hash user_$arg_username; server 127.0.0.1:8000; server 127.0.0.1:8001; server 127.0.0.1:8002; } server { listen 80; location / { proxy_pass http://backends; proxy_http_version 1.1; proxy_set_header Connection ""; } }}上述配置中,我們用8000,8001和8002三個端口模擬了3個上游服務器,默認使用輪詢負載均衡算法,而且三個的權重均為1。進行如下的 http 請求操作,可以看到 Nginx 轉發 http 請求會均勻地分配到3個服務器上。[shen@shen ~]$ curl http://180.76.152.1138000, server[shen@shen ~]$ curl http://180.76.152.1138001, server[shen@shen ~]$ curl http://180.76.152.1138002, server[shen@shen ~]$ curl http://180.76.152.1138000, server
在 nginx.conf 中加入如下的測配置:...http { server { listen 8000; return 200 '$uri\n'; } server { listen 9001; location /test { proxy_pass http://127.0.0.1; } } server { listen 9002; location /test { proxy_pass http://127.0.0.1/xyz; } }}...啟動 nginx 后,通過請求服務器的8000端口,我們可以知道請求的 uri 值,然后測試經過兩種類型的 proxy_pass 配置后最后的 uri 的值。具體操作以及結果如下:# 測試8000端口顯示的uri值[shen@shen ~]$ curl http://180.76.152.113:8000/test/abc/test/abc# 9001端口配置中proxy_pass后面的URL不帶URI[shen@shen ~]$ curl http://180.76.152.113:9001/test/abc/test/abc# 9002端口配置中proxy_pass后面的URL帶URI,會替換到匹配的/test[shen@shen ~]$ curl http://180.76.152.113:9002/test/abc/xyz/abc
本節講解了 HTTP 協議中的不同方法,通過一個具體的例子,講解在 Flask 應用中,如何處理指定 HTTP 方法的請求。對常用的 HTTP 方法,使用思維導圖概括如下:
Http 和 TCP/IP 都是協議,它們的不同之處在于:HTTP 是瀏覽器和后臺服務之間的語言,而 TCP/IP是電腦之間的語言(相同的語言才能互相理解雙方要表達的意思)。Http 本身只是約定了傳輸的時候文字要是什么格式,具體文字如何轉成物理的高低電平穿越電腦實現傳輸的過程它是不知道的。所以它需要借助專業的人士 TCP/IP 來處理。TCP/IP 是專門解決主機之間信息傳輸的,它不局限于為 Http 服務,像發送郵件也有自己的郵件協議(SMTP),它的底層也需要借助 TCP/IP 來實現。(TCP/IP是整套完整的網絡傳輸框架模型,HTTP 也是屬于它里面的應用層)。
如果我們需要擴展現有的表達式,我們可以使用 Spring Bean 里的方法。例如,使用自定義 Bean WebSecurity 中的 check 方法:public class WebSecurity { public boolean check(Authentication authentication, HttpServletRequest request) { ... }}我們可以在配置文件中這樣寫:<http> <intercept-url pattern="/user/**" access="@webSecurity.check(authentication,request)"/> ...</http>或者在 Java 中直接加入配置:http .authorizeRequests(authorize -> authorize .antMatchers("/user/**").access("@webSecurity.check(authentication,request)") ... )
HTTP 協議是 Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫, 用于從萬維網(World Wide Web)服務器傳輸超文本到本地瀏覽器的傳送協議。HTTP 協議工作于客戶端-服務端架構為上。瀏覽器作為 HTTP 客戶端通過 URL 向 服務端發送請求,服務端根據接收到的請求 URL,向客戶端發送響應信息。HTTP 請求-響應模型如下所示:
Spring Security 提供了一系列默認 Http 安全響應頭,我們可以便捷的配置它們。例如,為 X-Frame-Options 指定值 SAMEORIGIN:@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) { http.headers(headers -> headers.frameOptions(frameOptions -> frameOptions.sameOrigin())); }}如果不希望默認頭被自動添加,可以通過如下方式配置,例如僅添加 Cache Control 頭:@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http // ... .headers(headers -> headers // 取消自動添加默認頭 .defaultsDisabled() // 添加 CacheControl 頭 .cacheControl(withDefaults()) ); }}或者通過以下方式禁用所有 HTTP 安全響應頭:@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.headers(headers -> headers.disable()); }}
Https 并不是新的一種協議,它是 Http 協議的基礎上面封裝了一層 SSL(Secure Socket Layer),Https 底層跟 Http 一樣是經由 TCP 通信的。SSL 并不是 Http 特有的,所有應用層協議都可以使用 SSL 進行安全通信。
我們只需要在 http 指令塊中配置 log_format 指令和 access_log 指令即可。測試的配置如下:...http { ... log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; # 和上面的日志格式無關 server { listen 8000; return 200 '8000, server\n'; } ...}...log_format 指令是指定打印日志的格式,access_log 指令指定日志輸出的路徑以及指定使用前面定義的日志格式。在配置好日志相關的指令后,重啟 Nginx,并發送一個 Http 請求,就可以在對應的路徑上看到相關的日志信息了。# 模擬發送http請求[shen@shen Desktop]$ curl http://180.76.152.113:80008000, server[shen@shen Desktop]$ curl -H "X-Forwarded-For: 1.1.1.1" http://180.76.152.113:8000# 查看打印的日志,和前面配置的日志格式進行對比[root@server nginx]# tail -2 logs/access.log 103.46.244.226 - - [02/Feb/2020:20:52:05 +0800] "GET / HTTP/1.1" 200 13 "-" "curl/7.29.0" "-"103.46.244.226 - - [02/Feb/2020:20:57:03 +0800] "GET / HTTP/1.1" 200 13 "-" "curl/7.29.0" "1.1.1.1"
客戶端可以新增、修改、刪除聯系人,相應的 URI 如下:HTTP 方法行為URIPOST新增聯系人http://localhost/usersPUT修改 id 為 123 的聯系人http://localhost/users/123DELETE刪除 id 為 123 的聯系人http://localhost/users/123
Http 直接跟 TCP 傳輸層交互,而 Https 多了一層 SSL 協議,正式這個協議讓 Https 有了數據加密、身份認證的證書和數據完整性保護這些功能。SSL 是獨立于 HTTP 的協議,所以不光是 HTTP 協議,其他運行在應用層的 SMTP 和 Telnet 等協議均可配合 SSL 協議使用??梢哉f SSL 是當今世界上應用最為廣泛的網絡安全術。
配置文件的目的是將我們自定義的實現類交給 Spring 的容器管理。因為 Spring 框架核心功能之一就是 IoC 控制反轉,目的是將對象實例化的動作交給容器。還記得第一節介紹的嗎?不記得了?走你,剩下的我們繼續。最終 Spring 的配置文件如下:<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd"> <!-- 此標簽的作用 是實例化UserServiceImpl類的實例 交給 Spring 容器 --> <bean id="userService" class="com.wyan.service.impl.UserServiceImpl"></bean></beans>
http 最常用的協議,用于客戶端主動向服務器發送請求,單向傳遞;ajax HTTP 的擴展版,底層還是 HTTP 協議,只不過客戶端是無刷新的;comet 也是基于 HTTP 封裝的,使用 HTTP 長連接的方式,原理大致是將 HTTP 的timeout 設置較長,服務器有數據變化時返回數據給客戶端,同時斷開連接,客戶端處理完數據之后重新創建一個 HTTP 長連接,循環上述操作(這只是其中一種實現方式);websocket 這是 HTML5 中的新標準,基于 socket 的方式實現客戶端與服務端雙向通信,需要瀏覽器支持 HTML5;Adobe Flash Socket 這個也是使用 socket 的方式,需要瀏覽器支持 flash 才行,為了兼容老版本的瀏覽器;ActiveX object 只適用于 IE 瀏覽器;目前尚沒有一種方式能兼容所有的瀏覽器,只能針對軟件的目標客戶人群做一定的兼容。sse 服務端單向推送。
Android 系統為我們提供了 HttpUrlConnection 接口用于實現 Http 請求。自從 Android API9 開始,HttpUrlConnection 就成為了 Android App 推薦使用的內置 Http 庫。使用它無需添加任何依賴,打開網絡權限:<uses-permission android:name="android.permission.INTERNET" />就可以訪問 Http 資源了,可以說相比第三方框架
在 nginx.conf 中加入如下防盜配置:...http { ... server { listen 9008; location / { valid_referers none blocked *.domain.pub www.domain.com/nginx server_names ~\.baidu\.; if ($invalid_referer) { return 403; } return 200 "valid\n"; } } ...}...重新加載或者啟動 Nginx 后,我們進行如下操作:[shen@shen Desktop]$ curl -H 'referer: http://www.domain.com/test' http://180.76.152.113:9008 <html><head><title>403 Forbidden</title></head><body><center><h1>403 Forbidden</h1></center><hr><center>nginx/1.17.6</center></body></html>[shen@shen Desktop]$ curl -H 'referer: http://www.domain.com/nginx' http://180.76.152.113:9008 valid[shen@shen Desktop]$ curl -H 'referer: ' http://180.76.152.113:9008 valid[shen@shen Desktop]$ curl http://180.76.152.113:9008 valid[shen@shen Desktop]$ curl -H 'referer: http://www.domain.pub/test' http://180.76.152.113:9008 valid第一個 http 請求 referer 的值存在,但是沒有匹配后面的域名,所以返回403。其余的請求中 referer 值要么不存在,要么沒有這個頭部,要么匹配了后面的域名正則表達,都通過了 referer 校驗,所以都返回 “valid” 字符串。我們通過構造不同的 referer 頭部字段成功的繞過了 Nginx 的referer 模塊校驗,也說明了這種防盜的方式極不靠譜。
application.xml 是 Spring 上下文容器所關聯的配置文件,可稱其為全局上下文對象的關聯配置文件。<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config></context:annotation-config> <context:component-scan base-package="com.mk.web"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan></beans>元素解釋說明:context:annotation-config: 啟動注解支持,建議需要全局上下文對象創建、維護的對象使用注解的方式;context:component-scan: 掃描位置,需要排除開 Spring MVC 容器對象掃描的位置。Tips: application.xml 文件中一般用來配置業務層邏輯組件、數據層邏輯組件、通用組件、第三方組件相關的信息。
HTTP 協議應該是前端、后端、測試開發人員最常接觸的網絡協議了,因為這是網站和用戶之間傳輸信息的直接渠道。面試官考察 HTTP 相關的問題,也是為了了解候選人的開發基本功,為了熟悉本小結的知識,大家也可以了解下發送 HTTP 的 Postman 開發工具,以及 HTTP 網絡抓包的 Wireshark 工具。
本節討論了通過 HTTP + SSL 的方式,規避 HTTP 協議在安全上的不足。HTTP 協議存在安全隱患,容易遭到惡意攻擊,例如中間人攻擊;HTTP 安全時傳輸層安全的范疇,可以通過重定向 HTTP 連接和強制安全傳輸的方式增加其安全性;Spring Security 支持通過配置將 HTTP 請求轉換為 HTTPS 請求;Spring Security 支持為 B/S 應用強制使用安全傳輸。下節我們討論如果通過 Spring Security 統一不同 Web 容器間的訪問控制差異。
log 階段是 http 請求 11 個階段中的最后一個階段,這個階段主要的任務就是記錄請求的訪問日志。這個階段主要涉及的是 ngx_http_log_module 這個模塊。該模塊提供了幾個常用指令,如 access_log 和 log_format 指令,分別定義了請求日志的記錄文件以及記錄的日志格式。# 官方例子log_format compression '$remote_addr - $remote_user [$time_local] ' '"$request" $status $bytes_sent ' '"$http_referer" "$http_user_agent" "$gzip_ratio"';access_log /spool/logs/nginx-access.log compression buffer=32k;# access_log指令用法Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];access_log off;Default: access_log logs/access.log combined;Context: http, server, location, if in location, limit_except# log_format指令用法Syntax: log_format name [escape=default|json|none] string ...;Default: log_format combined "...";Context: http# 是否打開日志緩存Syntax: open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];open_log_file_cache off;Default: open_log_file_cache off;Context: http, server, location
HTTP Strict Transport Security(HSTS)頭,在 Spring Security 中是被默認開啟的,我們可以修改它的默認狀態,如下:@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .headers(headers -> headers .httpStrictTransportSecurity(hsts -> hsts .includeSubDomains(true) .preload(true) .maxAgeInSeconds(31536000) ) ); }}
上節我們討論了 HTTP 請求中,如何通過配置其頭部參數達到安全性提升的效果,本節將討論 HTTP 協議層面的安全性提升方法。HTTP 通訊協議是一種明文傳輸協議,存在安全隱患,所以通常我們會使用 TLS 方式保障其安全。本節我們主要討論 Spring Security 中的 HTTP 安全。