iT邦幫忙

0

POST 接收資料容量限制

請教各位前輩大大,因為工作需要最近在自學vue(vue-cli)以及laravel 8目前遇到一個問題,我在前端發一個POST請求到後端要撈資料庫中其中一頁的資料,但是資料庫中如果資料多到一定的筆數就會前端就會報跨域的錯誤,只要少於就正常接收,用Postman卻都正常抓到資料,也測試過後端確實有撈到資料,就是在回傳到前端時這段不知道是哪裡有問題。前端用npm run dev後端用php artisan serve啟動的。

只要資料庫筆數多於20筆就報錯。
https://ithelp.ithome.com.tw/upload/images/20201111/20131360Bi11WZR9Hp.png
https://ithelp.ithome.com.tw/upload/images/20201111/20131360EXjm2a3rz1.png

少於20筆就正常返回資料
https://ithelp.ithome.com.tw/upload/images/20201111/20131360xz3m9jXqAL.png
https://ithelp.ithome.com.tw/upload/images/20201111/20131360YFp2zuUOYW.png

這是前端封裝過的post請求的程式碼
https://ithelp.ithome.com.tw/upload/images/20201111/20131360xRAkm6SvZH.pnghttps://ithelp.ithome.com.tw/upload/images/20201111/20131360UCDR8OvU1f.png

這是後端接收的程式碼
https://ithelp.ithome.com.tw/upload/images/20201111/201313608Yak84np5p.pnghttps://ithelp.ithome.com.tw/upload/images/20201111/20131360OCps0shNlY.png

---更新一下------------------------------------------------------------------
我後端也有照https://medium.com/%E4%B8%80%E5%80%8B%E5%B0%8F%E5%B0%8F%E5%B7%A5%E7%A8%8B%E5%B8%AB%E7%9A%84%E9%9A%A8%E6%89%8B%E7%AD%86%E8%A8%98/laravel-%E4%BD%BF%E7%94%A8-middleware-%E8%A7%A3%E6%B1%BA-access-control-allow-origin-%E7%9A%84%E5%95%8F%E9%A1%8C-18237e4f77d4
這篇做了一個中間件如下,

https://ithelp.ithome.com.tw/upload/images/20201111/20131360Io33i2gGeA.png
我也測試過這支有在運作。

有勞各位前輩看看我問題到底出在哪,謝謝!

--------------------------------------以解決---------------------------------問題出在後端api返回的時候我用echo不知為何數據量少可以正常傳遞,但數據量大一點會報錯,把echo改成return就正常了,詳細可看樓下大大的解答。

看更多先前的討論...收起先前的討論...
froce iT邦大師 1 級 ‧ 2020-11-11 14:02:20 檢舉
你這本來就該做跨域設定,建議直接就先處理跨域問題吧。
然後超過一定筆數的話,我個人是沒遇到過。
咖咖拉 iT邦研究生 4 級 ‧ 2020-11-11 14:08:36 檢舉
看錯自刪
austin iT邦新手 5 級 ‧ 2020-11-11 14:19:07 檢舉
froce 大大你好,我後端已經有寫一支中間件處理跨域的問題了。還是我有那裡有BUG呢?
通靈亡 iT邦研究生 3 級 ‧ 2020-11-11 14:26:31 檢舉
>只要資料庫筆數多於20筆就報錯。
有時候錯誤訊息寫CORS,實際的問題是出在後端的程式碼
有可能是你處理分頁那邊的程式碼有問題

這個狀況我經常遇到,少於20筆正常就可以確定不是CORS的問題
另外,為什麼你的API回傳給前端,是用echo而不是return... ?
austin iT邦新手 5 級 ‧ 2020-11-11 14:39:44 檢舉
可是我沒有做分頁的處理,我後端只有和資料庫要資料,要到資料後我只有簡單包成$data['code']=回傳的資料 ,然後就echo $data回去。不一定是20筆如果資料文字少一點會改變筆數,但還是有個上限,超過就一樣報錯。
austin iT邦新手 5 級 ‧ 2020-11-11 14:41:45 檢舉
另外,為什麼你的API回傳給前端,是用echo而不是return... ?
=>我原本用get測試看看能不能渲染在頁面上,忘了改謝謝提醒。
通靈亡 iT邦研究生 3 級 ‧ 2020-11-11 14:55:43 檢舉
超過20筆的時候,你在return 之前使用 dd($data)
進到那個API網址看一下結果是什麼
austin iT邦新手 5 級 ‧ 2020-11-11 15:01:52 檢舉
直接用瀏覽器訪問?因為我是用post接收所以會報The GET method is not supported for this route. Supported methods: POST.
austin iT邦新手 5 級 ‧ 2020-11-11 15:02:58 檢舉
我有試過用get的話能直接渲染的。但就是傳不到前端。
通靈亡 iT邦研究生 3 級 ‧ 2020-11-11 15:03:11 檢舉
你改成get看看,沒問題再改回post
先確定dd出來會不會噴錯
austin iT邦新手 5 級 ‧ 2020-11-11 15:11:29 檢舉
大大我找到問題了..是那個echo,改成return就正常了。非常感謝。
通靈亡 iT邦研究生 3 級 ‧ 2020-11-11 15:14:08 檢舉
果然... 我直接在下面補充
給之後遇到類似問題的人參考 (有時噴CORS有時沒有)
austin iT邦新手 5 級 ‧ 2020-11-11 15:16:06 檢舉
非常感謝

2 個回答

3
通靈亡
iT邦研究生 3 級 ‧ 2020-11-11 15:19:39
最佳解答

如果遇到有時候噴CORS,有時候正常沒噴
通常很有可能是後端沒正確return 回應
或者過程中出現例外沒有做好try catch

因此程式碼遇到例外中止在後端,無法正確回應設定CORS之後的回應
前端那邊就會噴出CORS的錯誤訊息

4

基本上,跨域問題不會跟筆數多少有連帶關係。
我推測是筆數多有跑其它的地方去發生跨域的問題。

所以再來幾個建議。

1.本機開發也盡量用域名方式來開發。可以免掉一些上線後的bug存在。
2.如1說的,域名如果是在自已本機開發。可以不需要用真實域名。直接改host文件來開發處理就好
3.跨域的問題常發生在不同port的情況下。這點要很小心。
4.跨域的設定值可以先用直接對應域名設定。以下是先萬用的設定方式給你使用。

////////// 萬用模式(end) ///////            
$url = request()->server('HTTP_REFERER');
$urlArr = parse_url($url);
$httpType = $urlArr['scheme'] ?? 'error';
$host = $urlArr['host'] ?? 'error';
$port = $urlArr['port'] ?? '';
            
$setHost = $httpType.'://'.$host.($port ? ':'.$port : '');            
////////// 萬用模式(end) ///////
        if($setHost){
            return $response->header('Access-Control-Allow-Origin', $setHost)
                ->header('Access-Control-Allow-Methods', '*')
                ->header('Access-Control-Allow-Headers', 'Origin, Methods, Content-Type, Authorization')
                ->header('Access-Control-Allow-Credentials', true);
        }else{
            return $response;
        }

利用上面的程式碼。可以先萬用模式處理。等要正式上線。再調整為安全的模式。

另外要注意到你用的中間件如有碰到需要輸出的。全都要加上。
我之前原本也是要做統一輸出。但常常會像你一樣突然發生cors的問題。
後來才注意到有先後執行的輸出問題。但我中間件又不好調整位置。(會依情況不同的應用)
所以索性我將輸出放到一個 Repositorys 。再用中間件去做輸出對應處理。

public function handle($request, Closure $next)
    {
        $url = $request->server('HTTP_REFERER');
        if(!$url){
            abort(404);
        }        
        $userRep = new userRep;
        if($userRep->siteToUser($url,$request)){
            $next = $next($request);
            $next = systemRep::responseCors($next);//這隻就是處理的
            return $next;
        }else{
            abort(404);
        }
    }

以上給你參考吧。

austin iT邦新手 5 級 ‧ 2020-11-11 15:03:28 檢舉

謝謝大大

我要發表回答

立即登入回答