001.POST Not Support

weixin_33751566發表於2018-08-05

故事

離四點還有一個小時,還有個批量回復的功能沒有做完,自從上次被誇了之後,在專案的估時上面儘可能地壓縮時間,希望能夠更快完成任務,然後提交上線,但是,估計這一次,還是不行,週會不去開了。

後臺寫完,跑了測試用例,功能基本上就是我要的了,現在就差Web層的邏輯和前臺的頁面以及js。其實最討厭寫的還是前臺的頁面,邏輯,莫名其妙會花很長的時間,即使只是調整一些樣式,拼裝一些資料,在大前端,前後端分離的背景下,這已經是最低階的活兒。但是還是要得把整個功能給做完,至少自己還是能夠控制住的。

把之前單個提交的html程式碼拿過來,建了一個新的html檔案,在後臺web層寫了一個方法跳轉到這個html頁面。html頁面的樣式也很簡單,就是一個簡單的form表單。

<form class="form" action="" method="post" id="human">
    id:<input name="id" id="id"/><br/>
    名字:<input name="name" id="name"/><br/>
    年齡<input name="age" id="age"/><br/>
    <button type="submit" id="subBtn">提交</button>
</form>

既然貼了html,接著就是用js組裝資料,然後使用ajax提交到後臺。繼續貼程式碼唄。

  $(function(){
        var postNotSupport = {
            init: function() {
                this.initEvent();
            },
            initEvent: function() {
                var _this = this;
                // post not support
                // _this.postNotSupport;
            },
            postNotSupport: function() {
                var _this = this;
                _this.saveAjax();
            },
            saveAjax: function() {
                var human = {
                    id:$("#id").val(),
                    name:$("#name").val(),
                    age:$("#age").val()
                }

                $("#subBtn").on("click", function() {
                    $.ajax({
                        url:"/postNotSupport/save",
                        type:"post",
                        contentType:"application/json",
                        data:JSON.stringify(human),
                        sync:true
                    });
                })
            }
        }
        postNotSupport.init();
    })

後臺是使用SpringMVC去接的,

@RequestMapping(value = "/postNotSupport/save", method = RequestMethod.POST)
@ResponseBody
public Response save(@RequestBody Human human) {
    System.out.println(human);
    return Response.success();
}

完事具備,就等除錯了。可是,讓我想不到的一幕竟然出現了,當我點選提交的時候,出現了‘POST’ not support的錯誤,經驗告訴我,這個錯誤和POST的關係幾乎為0,因為沒有一個人會犯一個前臺是POST提交的方式,而後臺確實用GET去接受的錯誤,而且這個錯誤實在是太容易發現了。(後面就是我的打臉時刻),再按照以往的經驗,如果出現這個錯誤,那麼一定就是後臺報的錯,我只需要看後臺報錯的異常堆疊資訊,就可以解決了。

以往的經驗,在一定的程度上,是可以幫助人的,但是在絕大多數的情況下,都是坑人的。經驗真的就像一個圈圈一樣,把你畫到圈圈裡面,然後就只能夠看到圈圈裡面的東西,外面的東西就看不到,頗有一葉障目不見泰山的感覺。

我繼續往下拉異常的資訊,可以,讓我發慌的事情出現了,後臺就只拋了POST not support的異常,往下的就是一些sql語句資訊,很鬱悶,心裡想著,不科學吧。看了下時間,已經是四點半了,週會已經開了半個小時,不知道他們的色眼看人看得怎麼樣。不去想了,五點前解決問題,然後上線吧。

在web層打了一個斷點,跑去頁面重新又試了一下,idea的黃色閃動亮起,我知道,這時候的程式在這個斷點下停下來。切換到idea,紅色的高亮如期而至,看了下接受的資料資訊,從前臺發過來的json,在後臺都轉換成的物件,這時候還沒有報錯。繼續向下執行,程式進入到了Service層的方法,同時,那個可怕的錯誤也開始顯現,繼續執行,DAO層插入資料,返回前臺,一切都很順利,除了那500的錯誤,那個post not support。

既然後臺沒錯,那就去前臺的js排查吧,在ajax前面和後面的位置上打上debugger的標準,讓程式在相關的地方停下來,當js執行到第一個debugger的時候,一切都相安無事,當執行到第二個debugger的時候,資料還沒有返回到前臺,異常就出現了。嘆了口氣,看了下時間,已經是5點,估計是發不了版了,如果失敗了,還得麻煩運維他們,而且週末也來了,在這個節骨眼上,還是不釋出吧,線上還執行著一個正常的版本,而且這個版本還執行得挺好的。於是,自己放鬆下了神經,也許卸下壓力,可以讓自己能夠排查出問題來。

開啟百度,罵了一聲,其實百度的搜尋質量一般般,奈何用不了翻牆的軟體,就暫時用百度吧。百度的搜尋結果,基本上都千篇一律,某一篇博文出來,複製了一次又一次,所以即使點選去十幾個連結,內容基本都一樣。上面講的如果是json返回,需要加@ResponseBody,method的get方法和post方法要寫清楚,諸如此類的,我都一遍又一遍地檢查,什麼都是按照流程來的,應該不會有錯。

靈光一閃,想想百度坑人的事情,想想網路上99%的都是錯誤的,只有1%的是不一定是對的原則。我默默開啟官網,spring的官網,真TM慢。等了半天,載入出來了,找到SpringMVC的內容,看了下的例子,啊,為什麼一毛一樣,都能夠出錯???心裡一萬個問號,同時有一萬個草泥馬在奔跑。時間來到五點半,他們開會也回來了。胖子回來,喝了口水,我心裡嘀咕著,“那個上不了線了,我還在處理,還沒開發完,週一上吧”,胖子點了點頭表示同意。

繼續debug,怎麼還繼續下去!!!只能求救呀!!!

拍了拍胖子的桌面,說我遇到了一個post不支援的錯誤,問怎麼解決。呃,好吧,受到了無情的嘲諷,post不支援,你是用post去提交get請求了吧。我據理力爭,ajax和後臺都是post的。不可能出現不對應的情況。這時候,由於微信的上線,boss去忙其他的

嘿,大芳,你解決過post不支援的問題嗎?大芳輕蔑一下,你是不是用post去提交get請求了,來來來,開啟程式碼,讓我看看,作為部門後臺開發的唯一一名女將,多少有點王者風範。你把這個{}去掉,嗯,去掉,跑一遍,錯誤還是如期而至,你這個用PostRequest吧,改掉,跑一遍,呵呵。然後我按照我一開始的debug流程,又跑了一遍。

解決不了,就只能等待。

時間到了8點半,我已經很絕望地坐了4個小時了,這4個小時,我都在處理這個虛無縹緲的bug,彷彿一切都不順利,我到底做錯了什麼。胖子忙完其他的事情,招呼過來,坐下,開始debug,同時,也圍過來一群同事,在討論這個問題。

事情並沒有預想的一樣,胖子坐下,掃了一下程式碼,說你這個少了個分號,然後拂袖而去,不留姓與名。他還是按照異常的堆疊資訊,一個斷點一個斷點打進去,打到最後一個類是DispatcherServlet,這是SpringMVC的內容分發器,前臺所有的請求都會經過這個類進行分發。ajax請求了一次,往後臺提交了一份資料,理論上,後面如果沒有其他的操作,這個請求就停止了,也就是沒有其他的請求會進來。但是,卻進來了一個頁面的POST請求。

原因已經知道了,就是這個頁面的POST請求,但是,他是怎麼觸發的,找到這一步,又一次陷入了迷茫,圍過來的一群人都不知道怎麼回事。繼續處理,在相關的POST請求上打上斷點,但是這個斷點並沒有進來,說明ajax請求之後的轉發並不是後臺處理的,原因就只有在前臺上。

看了一遍又一遍的js檔案,看不出有什麼問題,大家都陷入了絕望的時候,大巨集將了句,會不會是html的問題,胖子急忙去找html檔案,看到那個form表單,似乎明白了點什麼,“你這個form表單,也提交了一次吧?”,他把form相關的內容註釋掉,只留下input,再請求一次,這個bug就沒有出現了。

時間已經到了9點10分,經過了5個多小時,這個未知bug終於是定位到了。

可是為什麼在原來的頁面上,html檔案也是這麼寫的,卻沒有出現這個異常的資訊?

 $(function(){
        var postNotSupport = {
            init: function() {
                this.initEvent();
            },
            initEvent: function() {
                var _this = this;
                // 提交成功
                _this.validPost();
            },
            validPost: function() {
                var _this = this;
                $("#human").validate({
                    submitHandler:function(form){
                        _this.saveAjax();
                        return false;
                    }
                });
            },
            saveAjax: function() {
                var human = {
                    id:$("#id").val(),
                    name:$("#name").val(),
                    age:$("#age").val()
                }

                $("#subBtn").on("click", function() {
                    $.ajax({
                        url:"/postNotSupport/save",
                        type:"post",
                        contentType:"application/json",
                        data:JSON.stringify(human),
                        sync:true
                    });
                })
            }
        }
        postNotSupport.init();
    })

答案就在js檔案上面,原來的js是有做欄位規則校驗的,使用jquery validate的submitHandler方法提交表單,而且還寫了個return false的語句,這個return語句,正是jquery阻止瀏覽器預設行為的方法,也就是說,阻止了form表單的submit方法。呀,坑死了。以前的專案寫法真多樣,一個專案裡面表單提交,ajax提交的基本都混雜著,真是坑人的混雜。

不管,吃飯去。幾個小時的debug,加上花椒油,真的身心疲憊,真不想講話。

程式碼

k001_post_not_support

感悟

  1. 專案規範很重要!!!html的寫法,js的寫法,java的寫法都要按規範了,提交表單要不用submit,要不用ajax,混合雙打反而是坑了自己坑了後面的人;
  2. 寫後臺的太注重邏輯了,基本上debug都是集中在java和js檔案,而html檔案只會認為是一個頁面樣式,不會出岔子,而這次卻出了岔子;
  3. debug要整個流程跟下來,從前臺的頁面,js,到後臺的controller層,service層,dao層,都要跟;
  4. 如果解決不了,就不要鑽牛角尖,問下別人,或者喝個茶放鬆下;
  5. 框架的原理需要清楚,至少也要了解,這樣更容易排錯。

參考資料

  1. https://blog.csdn.net/u011450110/article/details/44691569

相關文章