您好,登錄后才能下訂單哦!
Nginx 405 not allowed 異常要怎么辦處理,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
今天遇到一個問題,當配置好的前端工程放到服務器上使用nginx啟動的時候,報了405 Not allowed 異常,在網上百度了一下,說是這個問題出現的原因是因為使用了post 請求去獲取靜態資源,我覺得很奇怪,請求的接口都是業務接口,并不存在請求靜態資源,是不是nginx對靜態資源理解有什么誤會,或者說我對靜態資源理解不對,抱著這個想法,我把靜態資源的概念又梳理了一遍:
靜態資源:指的就是在html中的js/css/jpg/png/xxx.json...等等這些在前端工程中需要提前配置或者編譯之后的文件,而且這些文件并不會時刻變化或者說變化周期比較長
好的,接下來我就試著根據百度出來的解決辦法都嘗試了一遍,畢竟網上這么多提出解決辦法的,總有一個能解決吧,于是就開始嘗試了各種網友的解決辦法:
在location
中配置error_page
,這個解決問題的思路是將post
請求轉換成get
請求,配置信息如下:
server { listen 80; server_name 域名; location /{ root /www/文件目錄; index index.html index.htm index.php; error_page 405 =200 http://$host$request_uri; } }
這樣寫是有問題的,有網友提到這樣寫只適用于post
請求中不帶參數的請求,帶參數的post
請求如果使用這種方式可能會導致參數體丟失
2. 修改nginx下src/http/modules/ngx_http_static_module.c文件,如下:
if (r->method & NGX_HTTP_POST) { return NGX_HTTP_NOT_ALLOWED; }
這個辦法是修改nginx的源碼,將這一段代碼注釋掉,重新編譯,注意,注釋的時候需要使用 /* */ 的方式,而不是 # 這個符號,不然會報錯,參考這個
3. 修改錯誤界面指向(網上多流傳這種方式,但是沒有改變請求方法,所以行不通,所以采用以下方法),代碼如下:
upstream static_backend { server localhost:80; } server { listen 80; error_page 405 =200 @405; location @405 { root /srv/http; proxy_method GET; proxy_pass http://static_backend; } }
這個處理的思路是將405的錯誤信息重新指向一個命名為@405
的location
地址,同時修改請求方式為get方法,這個方法同上面的第一個方法是一樣的。這個location
將請求重新發送給proxy_pass
中定義的static_backend
,upstream
原本是用來配置負載均衡地址的,這里直接給了一個后臺訪問地址,思路沒問題
不過,很不幸的是,上面這些方法中我試過了第一個和第三個,對我沒有效果,第二個我就不去試了,我覺得nginx這樣的設置肯定是有他的道理的,即使通過修改源碼暫時達到了預期的效果,那這樣也會帶來隱患,難道以后就不升級nginx了嗎,是吧,所以我覺得修改源碼是最不靠譜的辦法。
既然這幾個方法都沒有效果,那就看看后臺服務的日志有沒有收到請求,結果發現后臺服務啟動之后根本就沒有收到Nginx 的任何請求轉發,也就是說所有的請求(包括get
)都沒有到達后臺,此時我就開始懷疑是location
配置的問題,為什么這么說呢,因為如果是普通的405 not allowed
異常情況,至少get
請求是沒有問題的,但是在查看控制臺以及后臺服務后發現,后臺沒有接收到請求,而瀏覽器的控制臺中-network
一欄,get
請求的respone是一個靜態頁面,也并不是預想中的json數據,如下:
而在Headers
一欄顯示請求是OK的,如下:
根據這個情況我更加確定,這個問題并不是它表現出來的 405 not allowed,很有可能是由于 location
配置異常導致了 405 not allowed,順著這個思路我又復習了location
的配置,我原來的location 配置如下:
location = /demo { # rewrite ^.+demo/?(.*)$ /$1 break; proxy_pass http://localhost:19998; proxy_set_header Host $host:$proxy_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-NginX-Proxy true; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } location / { root /home/jenkins/workspace/demo-2.0/dist; try_files $uri $uri/ /index.html; proxy_redirect http:// https://; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
這是一個嚴格匹配模式,在location
中有3中匹配模式,參考這個,分別是:
location = patt {} [精準匹配]
location patt{} [普通匹配]
location ~ patt{} [正則匹配]
其中精準匹配的優先級最高 --> 普通匹配 --> 正則匹配。
我將location = /demo {}
修改成了location /demo {}
就解決了問題,為什么呢?
個人理解,精準匹配是需要指定到具體某一個訪問資源的,比如:location = /demo/index.html,應該這樣寫才對,我的post
請求中請求的url地址是一個很長串的地址,比如:localhost:19999/demo/user/query
這種,所以其實根本就沒有匹配到 /demo
,而是匹配到了最下面的 location / {}
這里,所以請求全都被發送到了主頁面上,導致nginx判斷所有的請求都是在請求一個index.html,這違反了nginx的設計原則,即:不允許靜態文件響應POST請求,所以才出現了***404 not allowed*** 的異常。
看完上述內容,你們掌握Nginx 405 not allowed 異常要怎么辦處理的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。