4

我正在尝试在 Chrome 中进行跨域JSONP调用,但我不断返回“未捕获的语法错误:意外的令牌:” 我尝试过:更改响应内容类型、设置 xhr 标头、JSON.stringify,几乎是大多数这里提供的解决方案,但到目前为止没有任何效果:-(

 $.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

有人有任何想法/建议吗?

4

3 回答 3

3

经过彻底的测试,很明显,当 ajax 期望返回 JSONP 时(由于跨域限制),无法捕获 JSON 对象结果。即使响应状态 = 200。

我一直在使用 jQuery AJAX 调用进行测试,试图查看是否仍然可以捕获结果——尽管浏览器抛出了解析错误——但这似乎不可能。看起来响应文本在 JS 工作完成后到达标头。

正如@Florian F. @Likwid_T @Christoph 上面所建议的那样,肯定需要服务器端脚本才能使其正常工作。其他开发人员似乎热衷于使用用 C# 编写的代理作为解决方案。

于 2013-02-15T13:27:08.427 回答
1

Christoph 是对的,您需要将答案包含在回调函数中,在您的情况下位于 PHP 文件的末尾:

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

或者如果您需要更复杂的对象

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

你可能需要稍微调整一下,但基本上每当我得到Unexpected token时,几乎总是一个语法错误,导致 jQuery 无法获取我的回调函数。

于 2013-02-13T13:17:36.030 回答
1

JSONP 不能开箱即用。

JSONP 通过将结果加载到脚本标签中来绕过跨域限制。

基本上,您的服务器必须启用 JSONP。

在发送响应之前,在服务器端做任何需要做的事情:

  1. 检查请求是否设置了“_callback”
  2. 如果设置,则使用 _callback 的值包装您的内容。
  3. 发送您的数据

PHP 中的代码示例:

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

它将使用正确的参数执行您的“完成”匿名函数。(JQuery 处理一切)

于 2013-02-13T13:01:46.253 回答