2013-02-13 300 views
4

我試圖做一個跨域JSONP呼叫在Chrome,但我不斷收到回「未捕獲的SyntaxError:意外的標記:」 我已經試過:改變響應內容類型,設置XHR頭,JSON.stringify,只是大多數這裏提供上,但該方案沒有奏效,到目前爲止:-(jQuery的AJAX JSONP錯誤「意外令牌」

$.ajax({ 
       type: "POST", 
       url: "https://www.virustotal.com/vtapi/v2/url/report", 
       crossDomain: true, 
       contentType: "application/json; charset=UTF-8", 
       dataType: 'jsonp', 
       data: { 
        apikey: "*", 
        resource: "http://www.1001freefonts.com/font/BaroqueScript.zip" 
       }, 
       jsonp: false, 
       jsonpCallback: receive, 
       success: function (data, textStatus, jqXHR) { 
        console.log("Data retrieved: " + data); 
       } 
      }).done(function() { 
       console.log('I think we are done here'); 
      }) 
     .error(function (e) { 
      console.log(arguments); 
      console.log('something went funny here'); 
     }) 
     .complete(function (xhr, status) { 

      console.log("complete"); 
     if (status === 'error' || !xhr.responseText) { 
      console.log('error'); 
     } 
     else { 
      console.log("data found:" + xhr.responseText); 
      //... 
     } 
    }); 
    }); 

    function receive(saveData) { 
     if (saveData == null) { 
      console.log("DATA IS UNDEFINED!"); // displays every time 
     } 
     console.log("Success is " + saveData); // 'Success is undefined' 
    } 

在調試器中,我可以看到的響應

{"permalink": "https://www.virustotal.com/url/b5b546fdbb49a2258e951c5e568a52655c65ac56112e39d15af0954a53b36772/analysis/1360339512/", "url": "http://www.1001freefonts.com/font/BaroqueScript.zip", "response_code": 1, "scan_date": "2013-02-08 16:05:12", "scan_id": "b5b546fdbb49a2258e951c5e568a52655c65ac56112e39d15af0954a53b36772-1360339512", "verbose_msg": "Scan finished, scan information embedded in this object", "filescan_id": "b7e13c0242e9690aba1f3da4b73d9c2e99a9b7fd03f542b55e694a34aaf9eca8-1360339519", "positives": 0, "total": 35, "scans": {"CLEAN MX": {"detected": false, "result": "clean site"}, "MalwarePatrol": {"detected": false, "result": "clean site"}, "ZDB Zeus": {"detected": false, "result": "clean site"}, "K7AntiVirus": {"detected": false, "result": "clean site"}, "Quttera": {"detected": false, "result": "clean site"}, "Yandex Safebrowsing": {"detected": false, "result": "clean site"}, "MalwareDomainList": {"detected": false, "result": "clean site"}, "ZeusTracker": {"detected": false, "result": "clean site"}, "zvelo": {"detected": false, "result": "clean site"}, "Google Safebrowsing": {"detected": false, "result": "clean site"}, "BitDefender": {"detected": false, "result": "clean site"}, "Opera": {"detected": false, "result": "clean site"}, "G-Data": {"detected": false, "result": "clean site"}, "C-SIRT": {"detected": false, "result": "clean site"}, "Sucuri SiteCheck": {"detected": false, "result": "clean site"}, "VX Vault": {"detected": false, "result": "clean site"}, "ADMINUSLabs": {"detected": false, "result": "clean site"}, "SCUMWARE.org": {"detected": false, "result": "clean site"}, "Dr.Web": {"detected": false, "result": "clean site"}, "AlienVault": {"detected": false, "result": "clean site"}, "Malc0de Database": {"detected": false, "result": "clean site"}, "SpyEyeTracker": {"detected": false, "result": "clean site"}, "Phishtank": {"detected": false, "result": "clean site"}, "Avira": {"detected": false, "result": "clean site"}, "Antiy-AVL": {"detected": false, "result": "clean site"}, "Comodo Site Inspector": {"detected": false, "result": "clean site"}, "Malekal": {"detected": false, "result": "clean site"}, "ESET": {"detected": false, "result": "clean site"}, "SecureBrain": {"detected": false, "result": "unrated site"}, "Netcraft": {"detected": false, "result": "clean site"}, "ParetoLogic": {"detected": false, "result": "clean site"}, "URLQuery": {"detected": false, "result": "unrated site"}, "Wepawet": {"detected": false, "result": "unrated site"}, "Minotaur": {"detected": false, "result": "clean site"}}} 

我已經在http://jsonlint.com/上驗證過它,它表明它是有效的JSON。

這裏是響應頭

cache-control:no-cache 
content-encoding:gzip 
content-length:695 
content-type:application/json 
date:Wed, 13 Feb 2013 12:00:33 GMT 
server:Google Frontend 
status:200 OK 
vary:Accept-Encoding 
version:HTTP/1.1 

任何人有任何意見/建議嗎?

+2

對於JSONP,你需要一個函數包裝器。普通的JSON對象不是有效的JSONP響應。服務器實際上是否能夠提供JSONP-Responses? – Christoph 2013-02-13 12:18:27

+0

另外'dataType:'jsonp',jsonp:false'看起來不正確。 – Christoph 2013-02-13 12:27:55

+1

@Christoph Re'dataType:'jsonp',jsonp:false'他們是正確的,查看文檔http://api.jquery.com/jQuery.ajax/ – Eric 2013-02-13 13:03:38

回答

1

JSONP不能開箱即用。

JSONP通過將結果加載到腳本標記中來繞過跨域限制。

基本上,您的服務器必須啓用JSONP。

什麼就做什麼需要,然後右鍵發送響應之前,要在你的服務器端完成:

  1. 檢查要求有「_callback」設置
  2. 如果設置,纏上_callback的價值內容。
  3. 送在PHP數據

代碼示例:

$responseString = '{"smthing":"val","smthingelse":"val2"}'; 
if (isset($_REQUEST['_callback'])) { 
    $responseString = $_REQUEST['_callback'] . '(' . $responseString . ');'; 
} 

它會用正確的參數執行你 '做' 匿名函數。 (JQuery的處理一切)

+0

是什麼讓你覺得,他可以修改服務器?如果他正在進行跨域請求,他很可能不會控制這一點。 – Christoph 2013-02-13 14:09:16

+0

因爲它是唯一的解決方案。跨域僅在您控制服務器或服務器自己接受時纔有用。下一個解決方案是在你自己的域上構建一個代理,將請求轉發給web服務。 – 2013-02-13 14:47:42

+0

@FlorianF。克里斯托夫是對的,我無法控制服務器。我的項目僅限於JS。 – Eric 2013-02-13 14:53:26

1

克里斯托夫是正確的,你需要包住你的答案在你的回調函數,在你的情況下,在PHP文件的末尾:

echo $_GET['receive'] . '(' . json_encode($yourResultObject) . ');'; 

,或者如果你需要一個更復雜的對象

echo $_GET['receive'] . '(' . json_encode(array(name1 => object1, name2 => object2, name3 => object3)) . ');'; 

您可能需要調整一下,但基本上每當我得到意外標記幾乎總是讓jQuery的不能讓我的回調函數語法錯誤。

+0

他沒有控制我認爲的serverside。否則在大多數情況下,您不必執行跨域請求。 – Christoph 2013-02-13 14:08:05

+0

@Likwid_T不幸的是沒有服務器端腳本可以參與。它必須保持JS。 是否有可能在JS中應用相同的操作? 我的回調函數沒有接收數據,即使我可以在響應頭中看到返回的JSON對象結果。 – Eric 2013-02-13 14:42:17

+0

等待我只是重讀一遍:你在響應中從服務器獲取數據? {「permalink」:「https://www.virustotal.com/url/b5b546fdbb49a2258e951c5e568a52655c65ac56112e39d15af0954a53b36772 ... etc?是否正確? – 2013-02-14 14:32:26

3

經過全面測試後,很明顯,當ajax預期返回JSONP(由於跨域限制)時,無法捕獲JSON對象結果。即使響應狀態= 200.

我一直在使用jQuery AJAX調用進行測試,試圖查看結果是否仍然可以被捕獲 - 儘管存在瀏覽器拋出的解析錯誤 - 但它似乎並不是可能。它看起來像JS工作完成後,響應文本到達標題。

As @Florian F. @Likwid_T @Christoph在上面提出了建議,確實需要服務器端腳本才能正常工作。其他開發人員似乎熱衷於使用用C#編寫的代理作爲解決方案。