iT邦幫忙

0

jquery beforeSend的問題

evey 2010-12-08 09:11:3812320 瀏覽

各位大大,請問~
我原本是要在SUMBIT之後,取一個單號值,但是這幾天研究下來,無論我怎麼取值,都無法在
beforeSend去取得,以下是我的程式碼,在GetID.asp取得一個單號,在success的時候將
值給予NUM 這是沒問題,但是sumbit之後沒辦法儲存單號,所以找到了,beforeSend
現在問題來了,我該如何將success(data)的值傳給beforeSend() ? 還是沒辦法這樣做?因
為測試結果雖然success和beforeSend的形態都是functon但beforeSend沒辦法接授json
[0].NUM,錯誤會顯示'0'是null或不是一個物件

$.ajax({       

  url :"GetID.asp",

  method : 'get',

  datatype : 'json', 

//success : function(data){         
   // var json = jQuery.parseJSON(data);            
   // var N1 = json[0].NUM;  
   // $("#NUM").val(N1);               
 // },

   beforeSend : function(){
    function(data){         
       var json = jQuery.parseJSON(data);            
       var N1 = json[0].NUM;  =>有問題
       $("#NUM").val(N1);                  
  }      
}); 

2 個回答

4
godstamp
iT邦新手 3 級 ‧ 2010-12-10 00:51:41
最佳解答

不曉得我是否有誤解了你的問題..

success(data) 的值(data)是送出處理成功後回傳的資料。
但 beforeSend() 是在傳送出去之前執行的動作,應該是無法將success(data)的值傳給beforeSend()..
如果是要在處理結果後另外做其他動作,可以使用 complete(),它是在 success() 之後執行的..
以下給你參考...

<pre class="c" name="code">
$.ajax({
	url:"index.php",
    dataType : "json",
    type: "POST",
    beforeSend:function(XMLHttpRequest){
		//送出前的動作
    },
	success:function(j){
		//送出請求成功後的動作
	},
    complete:function(XMLHttpRequest,textStatus){
		
        try{
            //解JSON字串成為物件
			var j = $.parseJSON(XMLHttpRequest.responseText);
			
			//完成的動作...
			
        }catch(err){
            alert(err);
        }
    }
});

以上的 j 如同你問題中 success(data) 的 data ...
如果傳回的資料為 JSON 格式的字串資料,需要透過 $.parseJSON() 解析轉換成物件(j)來使用,如果不是 JSON 格式的話 $.parseJSON() 會丟出例外,所以可以從 catch(err) 這裡的 err 來取得例外訊息及回傳的內容。

由於我是用在PHP程式中,可能與你的狀況不同...希望對你會有幫助^^

看更多先前的回應...收起先前的回應...
fillano iT邦超人 1 級 ‧ 2010-12-10 08:55:11 檢舉

datatype如果是json,需要用typeof判斷success callback 傳進來的j參數。如果在php中有使用header("Content-Type: text/json")的話,jQuery會自動把他parse成物件或陣列,否則他會是一個字串。所以要用typeof來判斷他是否是字串,再來操作。

godstamp iT邦新手 3 級 ‧ 2010-12-10 23:33:43 檢舉

更正一下,complete 是在資料送出處理完成後執行,但卻是在success之前就動作,上頭回答時說錯了...抱歉~

dataType 如果是json,success callback傳進來的參數,jQuery 都會將他視為 JSON 字串並試著parse成物件,如果此參數非JSON字串,jQuery 將不會對他 parse,而直接視為一般字串,如同在頁面上直接 echo 一樣,在php中並不需要特別使用 header("Content-Type: text/json"),都是相同的結果。

這邊會說需要透過 $.parseJSON(),是因為 complete callback 傳進來的參數 XMLHttpRequest 是包含各種資料的物件,其中有個 XMLHttpRequest.responseText 是處理完成後,我們希望送回來的資料,可惜它是個字串,後續運用上可能會有諸多不便,此時就需要 $.parseJSON() 將它轉成物件來使用,但它也可能不是JSON格式的字串,當 $.parseJSON() 遇到非JSON格式的字串,就會直接丟出例外訊息 Invalid JSON: .... ,在這裡如果未補獲例外,可能會在頁面執行上出現 JavaScript 的錯誤警告而影響到後續其他JavaScript的執行,所以此處需要 try catch 來處理丟出例外時的動作,至於實際的例外訊息內容,可以利用上頭的 code 試看看或查看 jQuery 原始碼。

fillano iT邦超人 1 級 ‧ 2010-12-14 16:10:15 檢舉

fillano提到:
再來操作

如果typeof 結果是Object,那就是jQuery幫你parse好了,不必再做一次。server response裡面沒有Content-Type: text/json這個header時,jQuery不會自動把他parse成物件。

所以typeof的結果如果不是Object,那就需要進一步處理,這個處理就包含了你說的$.psrseJSON()...我只是補充一下你沒提到的部份哈哈

godstamp iT邦新手 3 級 ‧ 2010-12-15 02:00:34 檢舉

可能個人用法不同吧!!
我在實作上是從來沒使用過Content-Type: text/json這個header,因為不管是否有這個header,server response 內容都是字串,只要 jQuery 的 ajax 有 datatype:"json",它在 success callback 時就會 parse,至於結果是使用 typeof 或其他方式去判斷都可以,只是此處在 php 中加這個 header 其實是多餘的。

也有人不使用 datatype:"json",而使用預設的 datatype:"text",再以自己的方式 parse (因為百分之百不會 parse 為物件),只是 datatype:"json" 在 success callback 這邊由 jQuery 內部使用 $.parseJSON() 和我們在 complete callback 自行使用 $.parseJSON() 都可以很明白的確認 response 的字串是否為 JSON 格式的字串。

fillano iT邦超人 1 級 ‧ 2010-12-15 09:48:12 檢舉

您要不要試一下...
html端:

<pre class="c" name="code">


<script src="js/jquery-1.4.2.min.js"></script>
<script>
$(document).ready(function(){
	$('#test').click(function(){
		$.ajax({
			url: 'test651.php',
			method: 'get',
			datatype: 'json',
			success: function(data) {
				alert(typeof data);
			}
		});
	});

});
</script>


<input type="button" id="test" value="test">

php:

<pre class="c" name="code">
<?php
header("Content-type: text/json");
echo "[{\"NUM\":3}]";

在php中把header這一行註解掉,html端得到的結果不一樣喔。

godstamp iT邦新手 3 級 ‧ 2010-12-15 21:47:32 檢舉

這個 code 的結果是不一樣的,因為 datatype: 'json' 沒有作用,正確應該是 dataType: 'json',所以此處的 dataType 是使用預設值。

很抱歉,前面有部份講錯了,現今 jQuery 版本的 dataType 預設值不再是 text ,而是會試著智能辨別 xml json script html 來 parse,所以在此處 dataType 未指定,才需要 header 來告知 jQuery 需視為 JSON 處理。

evey iT邦新手 5 級 ‧ 2010-12-16 14:25:32 檢舉

但我現在遇到一個問題
$.ajax({
url :"GetID.asp",
method : 'get',
dataType : 'json', =>若加入這行會變成從GetID.asp所傳回來的值'0'是null 或不是一個物件,若這行取消,可以取到值,顯示回傳的型態為string
success : function(data){
var json = $.parseJSON(data);
var N1 = json[0].NUM;
$("#NUM").val(N1);
alert(typeof data);

}

});

在GetID.asp
[
{
"NUM" : ["<%=cc%>"]
}

]

godstamp iT邦新手 3 級 ‧ 2010-12-16 22:45:02 檢舉

在此處應該是不需要再使用 $.parseJSON(),以下給你試試...

&lt;pre class="c" name="code">
$.ajax({ 
	url :"GetID.asp",
	method : 'get',
	dataType : 'json',
	success : function(j){
		$("#NUM").val(j[0].NUM[0]);
	}
});

不過你的值是 <%=cc%> 這樣的,直接放入網頁中的標籤來查看結果,有些瀏覽器可能只會看到空白,不曉得你是使用什麼瀏覽器?? 如果使用 google 瀏覽器可使用預設的開發人員工具,如果使用 firefox 瀏覽器可安裝附加元件 firebug 來查看會更容易些,不管使用這兩種的哪一種,都可以直接把 $("#NUM").val(j[0].NUM[0]); 這行改為 console.log(j[0].NUM[0]); 或 console.log(j); 來查看,回傳資料內容及型態都會在工具中很清楚的列出來,不像 alert() 常常都只跳個 string 或 [object Object] 這樣的訊息而已。

evey iT邦新手 5 級 ‧ 2010-12-20 09:19:42 檢舉

godstamp謝謝~~照你的方式,已成功
有個疑問為何不需要在使用$.parseJSON()?

ps.我大多都是使用IE

godstamp iT邦新手 3 級 ‧ 2010-12-20 21:02:16 檢舉

因為有 dataType : 'json' ,所以在 success callback 這邊,jQuery 內部會先 parse,前面會提到使用 $.parseJSON(),是在 complete callback 這邊才需要用到。

6
fillano
iT邦超人 1 級 ‧ 2010-12-08 10:39:15

你先看一下http://phorum.study-area.org/index.php/topic,63555.0.html我的回答,看看伺服器傳來的東西式否可以做JSON.parse()。

看更多先前的回應...收起先前的回應...
fillano iT邦超人 1 級 ‧ 2010-12-08 10:41:51 檢舉

JSON有一個嚴格的規定,我之前也中槍過...就是:{"NUM":3},裡面的key要用雙括號。你先看看是否是這個問題讓你JSON.parse()出問題。接得到值以後,再來調整你的程式。

evey iT邦新手 5 級 ‧ 2010-12-08 10:52:01 檢舉

$.get
$.getJSON
這樣的方式是都可以取值,沒有問題
只是放入
$.ajax({
beforeSend ->才有問題
})

我會一直卡在beforeSend,主要是送件前就將單號儲存,因為還在想該如何處理

fillano iT邦超人 1 級 ‧ 2010-12-08 11:07:39 檢舉

我想您Javascript不夠熟。Javascript裡面有一個重要的東西,就是許多事情都是「非同步」發生的,$('#NUM').val(N)瀏覽器不會在你呼叫的同時就立刻處理,html reflow需要花上大量時間(跟Javascript執行需要的時間比較),ajax呼叫也是一樣,會有網路的延遲。

如果你需要先用$.ajax取單號,然後再做一次$.ajax把資料送出,那第二次的$.ajax要放進第一次的success這個callback函數裡面做,這樣才有辦法保證事情是依照你想要的順序發生。我在論壇體面還沒有說清楚這個部份。

fillano iT邦超人 1 級 ‧ 2010-12-08 11:21:08 檢舉

另外,beforeSend不是這樣用的。傳給他的參數是XMLHttpRequest物件,你可以利用他在送出request之前作一些額外處理,例如加上cookie header。在這裡呼叫另一個$.ajax並不恰當,而且無法保證處理的順序。

evey iT邦新手 5 級 ‧ 2010-12-08 17:54:37 檢舉

我現在改變寫法,我直接去針對 sumbit去一個取值的動作,只是現在遇到一個問題
我在aa.js (以下的程式碼)
fuction xxx(str){

$.ajax({

url : "info.asp?st=" + str, =>str確定是有值的,或者
// data:{ st : "str"},
method: 'post',
success : function (){
code
}
});

}

在將st 傳到 bb.asp
cc=Request("st")
在asp->request都沒辦法去取jquery所傳過來的值,找了很久不知是哪邊的問題

evey iT邦新手 5 級 ‧ 2010-12-09 08:06:13 檢舉

上面將接收的網址打錯了,以下的才是

在將st 傳到 info.asp
cc=Request("st")

fillano iT邦超人 1 級 ‧ 2010-12-10 08:50:29 檢舉

你在javaworld@tw問的有人回嗎?

我要發表回答

立即登入回答