Object is not a function


 

坑一、是不是函數重名的問題

如圖報了一個這樣的錯,百度好多都說是函數名和html元素重名的問題。可是這個問題我想我這里是不存在的

可以看到就一個綁定事件,而且id名不是關鍵字

報錯是在$.ajax這一行,索性就把submit-info改了吧,但是還是沒有用。

 

坑二、是不是跨域的問題

看錯誤 6處錯誤,有5行是jQuery.js的錯誤,有一處是涉及到我自己寫的js錯誤

問題就在這了:at HTMLButtonElement.<anonymous>

也就是canvas加載服務器圖片,沒有允許跨域造成的。

關於跨域,百度的解決方案有很多。

首先普及一下知識。CORS是一個W3C標准,全稱是"跨域資源共享"(Cross-origin resource sharing)。CORS需要瀏覽器和服務器同時支持。目前,所有瀏覽器都支持該功

能,IE瀏覽器不能低於IE10。

它允許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。整個CORS通信過程,都是瀏覽器自動完成,不需要用戶參與。對於開發者來

說,CORS通信與同源的AJAX通信沒有差別,代碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有

感覺。因此,實現CORS通信的關鍵是服務器。只要服務器實現了CORS接口,就可以跨源通信。

請求流程

 

 

 1、preflight request發送請求

 2、preflight Response返回一些信息,驗證是否允許跨域,接而執行步驟3和4

這里是被請求的服務器后端允許請求端請求資源,才能實現跨域。

因此,我們需要在被請求的服務器端方法內允許對方請求,加入如下代碼

response.setHeader("Access-Control-Allow-Origin", "http://localhost:9105");
response.setHeader("Access-Control-Allow-Credentials", "true");

如果是SpringMVC4.2及以上的版本,則可以直接使用注解

@CrossOrigin(origins="http://localhost:9105",allowCredentials="true")

這個注解 allowCredentials="true" 默認為true,所以可以不寫。

可以看到這兩句代碼主要是給請求方set一個header

Access-Control-Allow-Origin 設置被允許請求的源,如果是允許所有源請求,設置為 *

Access-Control-Allow-Credentials 設置是否允許發送cookie

Access-Control-Allow-Origin是HTML5中定義的一種解決資源跨域的策略。
他是通過服務器端返回帶有Access
-Control-Allow-Origin標識的Response header,用來解決資源的跨域權限問題。

CORS請求默認不發送Cookie和HTTP認證信息。如果要把Cookie發到服務器,一方面要服務器同意,指定Access-Control-Allow-Credentials字段。另一方面,開發者必須在AJAX請求中打開

withCredentials屬性。否則,即使服務器同意發送Cookie,瀏覽器也不會發送。或者,服務器要求設置Cookie,瀏覽器也不會處理。

'withCredentials':true

 

坑三、后端解決同源

可以嗎?然並卵。其實到這里,我的問題自己也清楚了。因為我用的是獨立的文件服務器fastDFS存儲圖片,那么我的前端是通過代理訪問了圖片服務器。如果要加CrossOrigin,那么需要在tracker

設置。顯然不可能。所以我的解決方案是在后台把圖片轉成base64格式傳遞給前端,這樣就達到了同源。java代碼如下:

 

import sun.misc.BASE64Encoder;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
/**
 * 將文件服務器圖片編碼為Base64
 * @param url
 * @return
 * @throws Exception
 */
public static String encodeImageToBase64(URL url) throws Exception {
    //將圖片文件轉化為字節數組字符串,並對其進行Base64編碼處理
    System.out.println("圖片的路徑為:" + url.toString());
     //打開鏈接
    HttpURLConnection conn = null;
    try {
        conn = (HttpURLConnection) url.openConnection();
        //設置請求方式為"GET"
        conn.setRequestMethod("GET");
        //超時響應時間為5秒
        conn.setConnectTimeout(5 * 1000);
        //通過輸入流獲取圖片數據
        InputStream inStream = conn.getInputStream();
         //得到圖片的二進制數據,以二進制封裝得到數據,具有通用性
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        //創建一個Buffer字符串
        byte[] buffer = new byte[1024];
        //每次讀取的字符串長度,如果為-1,代表全部讀取完畢
        int len = 0;
        //使用一個輸入流從buffer里把數據讀取出來
        while ((len = inStream.read(buffer)) != -1) {
        //用輸出流往buffer里寫入數據,中間參數代表從哪個位置開始讀,len代表讀取的長度
            outStream.write(buffer, 0, len);
        }
         //關閉輸入流
        inStream.close();
        byte[] data = outStream.toByteArray();
        //對字節數組Base64編碼
        BASE64Encoder encoder = new BASE64Encoder();
        String base64 = encoder.encode(data);
        System.out.println("網絡文件[{}]編碼成base64字符串:[{}]"+url.toString()+base64);
        return base64;//返回Base64編碼過的字節數組字符串
    } catch (IOException e) {
        e.printStackTrace();
        throw new Exception("圖片讀取失敗,請聯系客服!");
    }
}
什么前端圖片加載不出來,what?這個base64是純字符串,請給它加上22位前綴data:image/png;base64,
img.src="data:image/png;base64,"+base64;


坑四、js版本的問題

然而問題還在繼續,但是這次有進展能向后台發送請求了,只是ajax請求的data參數是Object

 

最后問題找到在ajax傳遞的參數中用了關鍵字  length和width,但是奇怪的是上一個頁面用的相同的方法就行,這個頁面就不行了。
上個頁面只是多了個form表單,好吧閑話不多說。在html中把關鍵字改名,ajax提交成功了,進了后台。

 但是問題又來了,后台接收不到數據,走了很多彎路。解決辦法是把jquery-3.3.1.min.js換成jquery-1.8.3.min.js

 搞定

真是一波三折啊,程序猿一般人真干不了!

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM