1. 程式人生 > >Ajax和Servlet互動,報錯HTTP Status 405 – Method Not Allowed HTTP method GET is not supported by this URL

Ajax和Servlet互動,報錯HTTP Status 405 – Method Not Allowed HTTP method GET is not supported by this URL

學習慕課網的Ajax + Servlet實現搜尋框智慧提示的時候(https://www.imooc.com/learn/678)

自己打的程式碼Servlet類可以獲取到客戶端通過Ajax非同步傳送過來的資料,但是客戶端怎麼都無法獲取到服務端Servlet回傳的資料。

一直 xmlhttp.status = 405

怎麼都找不到原因。

js程式碼

/* 獲取xmlhttp物件的函式 */
function createXmlHttp() {
    var xmlhttp;
    if(window.XMLHttpRequest)
        xmlhttp = new XMLHttpRequest();
    else if(window.ActiveXObject) {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    return xmlhttp;
}


/* ajax從伺服器文字檔案獲取資訊 */
function change() {
    /*
    ajax 技術使用js來獲取伺服器的資料,達到區域性更新的效果
     */


    var xmlhttp = createXmlHttp();
    // state change 0-4
    xmlhttp.onreadystatechange = function() {
        // judge ok
        if(xmlhttp.status == 200 && xmlhttp.readyState == 4) {
            // refresh the part message
            document.getElementById("hello").innerHTML = xmlhttp.responseText;
        }

    };

    xmlhttp.open("GET", "../file/ajax_info.txt", true);
    xmlhttp.send();
}


/*
 輸入提示
 */
function getMoreContents() {
    // 獲取搜尋框內容
    var content = document.getElementById("search");
    if(content.value == "")
        return;
    // alert(content.value);
    var xmlhttp = createXmlHttp();

    // 傳送資料
    var url = "search?keyword=" + escape(content.value);
    xmlhttp.open("GET", url, true);
    xmlhttp.send("");
    // alert("test1");
    // 寫回調方法
    xmlhttp.onreadystatechange = function() {
          alert(xmlhttp.status);   // 成了 405 ...不是 200
          alert(xmlhttp.readyState);
        if(xmlhttp.status == 200 && xmlhttp.readyState == 4) {
            // 伺服器servlet通過json格式傳送資料給客戶端
            alert("....")
            var result = xmlhttp.responseText;
            var jsonobj = eval("(" + result + ")");  // 轉化json資料為普通資料
            setContent(jsonobj)
        }

    };

}

/*  設定關聯資料展示函式 */
function setContent(contents) {         //函式的引數不帶var宣告,函式錯了,整個js都錯了,函式內部某個錯誤不影響整體
    // 獲取長度來生成相應數量的<tr><td>
    alert("test")
    var size = contents.length;
    alert(size);
    for(var i = 0; i < size; ++i) {
        var nextNode = contents[i]; // 代表的是json資料轉js的資料第contents[i]
        alert(nextNode);
        // 生成<tr> <td>
        var tr = document.createElement("tr");
        var td = document.createElement("td");

        // 設定<td>屬性
        td.setAttribute("border", 0);
        td.setAttribute("bgcolor", "#FFFAFA");

        // 設定觸碰效果
        td.onmouseover = function() {
            this.ClassName = 'mouseOver';
        };
        td.onmouseout = function() {
            this.ClassName = 'mouseOut';
        };

        // 實現滑鼠點選一個提示時,提示會自動填入搜尋框
        td.onclick = function() {
            //
        };

        // 顯示 . 從內到外新增
        var text = document.createTextNode(nextNode);
        td.appendChild(text);
        tr.appendChild(td);
        document.getElementById("content_table_body").appendChild(tr);
    }


}



////////////   js函式沒有順序關係  /////////

Servlet        (完整程式碼: https://github.com/chgl16/Ajax-Servlet-search-prompt)

package top.chgl16.services;

/* servlet和json沒有自帶,需要下載依賴 */
import jdk.nashorn.internal.runtime.JSONListAdapter;
import net.sf.json.JSONArray;
import netscape.javascript.JSObject;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;


/**
 * @Lin
 * ajax 後臺程式碼
 * 1. 獲取ajax傳送過來的keyword
 * 2. 找到合適的資料返回
 */
public class SearchServlet extends HttpServlet {

    // 資料集
    static List<String> datas = new ArrayList<String>();
    static {
        datas.add("ajax");
        datas.add("ajax post");
        datas.add("ajax get");
        datas.add("ajax servlet");
        datas.add("chen guanlin");
        datas.add("jsp servlet");
        datas.add("mysql");
        datas.add("json");
        datas.add("chgl16");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // super.doGet(request, response);   //////////// 必須註解掉,不然405錯誤

        // 設定請求和響應編碼
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");

        System.out.println("伺服器servlet:");

        // 獲取客戶端傳送的keyword
        String keyword = request.getParameter("keyword");

        if(keyword == null) {
            keyword = "";
        }

        // 輸出獲取到的關鍵詞
        System.out.println("keyword " + keyword);

        // 獲得關鍵字後處理,得到關聯資料
        List<String> listData = new ArrayList<String>();
        listData = getData(keyword);

        // 給客戶端放回關聯資料的json格式
        System.out.println("關聯資料json格式: " + JSONArray.fromObject(listData));

        // 將資料傳回客戶端
        response.getWriter().write(JSONArray.fromObject(listData).toString());  // json格式在write()函式裡面要裝換成String型別

        System.out.println("----------------------------------------------------------------------------------------------");
    }


    public List<String> getData(String keyword) {
        List<String> list = new ArrayList<String>();
        for(String s : datas) {
            if(s.contains(keyword)) {
                list.add(s);
            }
        }
        return list;
    }
}

一直網上搜原因,都是指向Servlet問題,就是doPost()/doGet()方法(你使用那個)沒有重寫,預設呼叫了父類的造成的。自己已經重寫,但是一直錯。直到看到一行程式碼

super.doGet(request, response); 

沒有刪掉啊。還是直接呼叫了父類的先,雖然也呼叫重寫的。但是還是405了。註釋掉就行。