API 所有的響應狀態碼都是 200?

菜就多努力呀n 發表於2019-09-11

重現問題:

  1. 學習完 larabbs-weapp 上線的過程中,發現無論 dingo/apisetStatusCode 方法設定的 code 是什麼,伺服器都會返回一個 200http code,無論是伺服器錯誤 5xx,還是認證錯誤 4xx,伺服器都是 http code 返回的 200,貼一些程式碼和截圖:

    public function index(Request $request, Topic $topic)
    {
        $topics = $topic->query()->paginate(20);
        // 為了方便測試在「話題列表」這裡使用了 `setStatusCode`
        return $this->response->paginator($topics, new TopicTransformer())->setStatusCode(201);
    }

    技術債

大家不用太糾結 Tests 模組的響應,只是為了復現一下故障,總而言之就是 http code 沒有根據 setStatusCode 的設定來響應給客戶端。

解決思路:

  1. 之前碰到過一次 無論伺服器設定的 http code 是什麼,總是響應給客戶端 500http code,開啟日誌,發現是快取檔案的許可權問題,改一下許可權即可解決;
  2. 起初碰到本文描述的問題的時候,確實沒什麼思路,為此搜尋了一些文章,由於沒有抓到關鍵詞,檢索出來的文章也沒有成效;
  3. 首先,一樣的程式碼在本機的 homestead 上執行一切正常,放到阿里伺服器上便出現了這個問題,所以初步判斷是伺服器環境配置的問題;
  4. 得空還去翻了 dingo/apiissue ,發現了一個有相似問題的:where is the status code(204) when noContent() is called?,從這個 issue 進一步確定是伺服器配置的原因導致的該問題;
  5. 因為伺服器環境也比較簡單,所以思考了一下排查順序:nginx -> php-fpm -> php
  6. nginx.conf 中沒有設定 http code 的關鍵詞,判斷可能是 include 的檔案中導致的;
  7. 定位到 nginx.conf 站點配置檔案中的 include fastcgi_params,發現 fastcgi_params 中有一串程式碼片段:
    # PHP only, required if PHP was built with --enable-force-cgi-redirect
    fastcgi_param  REDIRECT_STATUS    500;
    • 經過一番除錯,發現不是這裡的問題,但好在找到了一些關鍵詞:redirectstatus
  8. 谷歌輸入關鍵詞檢索:php fastcgi redirect_status,瀏覽了一些網址,猜測可能會在 php.ini 中有線索;
  9. 找到 php.ini 中沒有註釋的 cgi 相關配置:
    • cgi.force_redirect = 0
    • fastcgi.impersonate = 1
    • cgi.rfc2616_headers = 1
  10. 經過一番調式發現是 cgi.rfc2616_headers 這個引數導致的,設定為 0,即可解決此問題。

後記

  1. 解決了介面響應的問題,又發現了新的問題:
    • 微信小程式呼叫的介面必須支援 https,所以下一步就是為我的 larabbs 配置 https,詳情請見下一篇文章 ~

刻意練習,日益精進。