Ajax跨域之ContentType為application/json請求失敗的問題

來源:互聯網
上載者:User

標籤:response   art   query   his   use   ini   java程式   other   失敗   

項目裡的介面都是用springmvc寫的,其中在@requestmapping介面中定義了consumes="application/json",也就是該介面只接受ContentType為application/json的請求。

介面寫好用工具測試介面都是可以正常請求,但是在瀏覽器中用ajax請求就不行。

百度一下,原來在使用Ajax跨域請求時,如果設定Header的ContentType為application/json,會分兩次發送請求。第一次先發送Method為OPTIONS的請求到伺服器,這個請求會詢問伺服器支援哪些要求方法(GET,POST等),支援哪些要求標頭等等伺服器的支援情況。等到這個請求返回後,如果原來我們準備發送的請求符合伺服器的規則,那麼才會繼續發送第二個請求,否則會在Console中報錯。

為什麼在跨域的時候設定ContentType為application/json時會請求兩次?其實JQuery的文檔對此有做說明。

contentType (default: ‘application/x-www-form-urlencoded; charset=UTF-8‘)

Type: Boolean or String

When sending data to the server, use this content type. Default is "application/x-www-form-urlencoded; charset=UTF-8", which is fine for most cases. If you explicitly pass in a content-type to $.ajax(), then it is always sent to the server (even if no data is sent). As of jQuery 1.6 you can pass false to tell jQuery to not set any content type header. Note: The W3C XMLHttpRequest specification dictates that the charset is always UTF-8; specifying another charset will not force the browser to change the encoding. Note: For cross-domain requests, setting the content type to anything other than application/x-www-form-urlencoded, multipart/form-data, or text/plain will trigger the browser to send a preflight OPTIONS request to the server.

注意Note後面的描述,在跨域的時候,除了contentType為application/x-www-form-urlencoded,multipart/form-data或者text/plain外,都會觸發瀏覽器先發送方法為OPTIONS的請求。

比如說,你原來的請求是方法方法POST,如果第一個請求返回的結果Header中的Allow屬性並沒有POST方法,那麼第二個請求是不會發送的,此時瀏覽器控制台會報錯,告訴你POST方法並不被伺服器支援。

 


圖中箭頭指向的Allow就是伺服器返回的支援的方法。

不僅如此,如果想要用ContentType:application/json發送跨域請求,伺服器端還必須設定一個名為Access-Control-Allow-Headers的Header,將它的值設定為 Content-Type,表明伺服器能夠接收到前端發送的請求中的ContentType屬性並使用它的值。否則第二次請求也是發不出去的,瀏覽器console會報錯,並提示你伺服器沒有設定Access-Control-Allow-Headers。

對應到我java程式的filter過濾器裡是這樣

 1 public class MyFilter implements Filter { 2      3     @Override 4     public void destroy() { 5         //System.out.println("過濾器銷毀"); 6     } 7  8     @Override 9     public void doFilter(ServletRequest request, ServletResponse response,10         HttpServletRequest httpRequest = (HttpServletRequest) request;11         String type=httpRequest.getMethod();12 13         if (type.toUpperCase().equals("OPTIONS")==true) {14             httpResponse.setHeader("Access-Control-Allow-Headers", "content-type, accept");15             httpResponse.setHeader("Access-Control-Allow-Methods", "POST");16             httpResponse.setStatus(200);17             httpResponse.setContentType("text/plain;charset=utf-8");18             httpResponse.setCharacterEncoding("utf-8");19             responseContentByte="{\"test\":\"OPTIONS\"}".getBytes();20         }21     }22 23     @Override24     public void init(FilterConfig arg0) throws ServletException {25          //System.out.println("過濾器初始化");26     }27     28 }

 

Ajax跨域之ContentType為application/json請求失敗的問題

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.