使用POST请求从不同的域获取JSON对象

时间:2014-06-16 23:55:42

标签: jquery ajax json

我一直在试图弄清楚如何通过ajax将POST请求发送到另一个域的页面。似乎我去过的每个地方都被告知,当它是跨域时,你不能简单地使用POST请求。

我正试图通过POST请求从USGS网站获取土壤信息。以下是解释流程的页面:http://earthquake.usgs.gov/hazards/apps/vs30/documentation.php 这是我的jQuery:

var postObj = {
    json: 'true',
    site_name: 'model',
    top_left_lat: 0,
    top_left_lon: 0,
    bottom_right_lat: 1,
    bottom_right_lon: 1,
    slope_type: 'stable',
    output_types: ['jpg', 'xyz', 'grd']
}

$.ajax({
    url: "http://earthquake.usgs.gov/hazards/apps/vs30/vs30.php",
    type: 'POST',
    dataType: 'jsonp',
    data: postObj,
    success: function(data) {
        console.log(data);
    }
});

这是我执行后的控制台:

Resource interpreted as Script but transferred with MIME type text/html: "http://earthquake.usgs.gov/hazards/apps/vs30/vs30.php?callback=jQuery111007…es%5B%5D=jpg&output_types%5B%5D=xyz&output_types%5B%5D=grd&_=1402961661663 ". jquery-1.11.0.min.js:4
Uncaught SyntaxError: Unexpected token < vs30.php:1

知道我做错了什么吗? USGS网站是否忘记了“Access-Control-Allow-Origin:*”?请帮忙!

1 个答案:

答案 0 :(得分:1)

JSONP不支持POST请求,因此您的请求将转换为GET请求,并将postObj中的信息附加到查询字符串。这就是API响应错误消息的原因(显然格式化为HTML)。

此外,Documentation不包含任何有关JSONP的信息。我认为他们只支持普通的JSON,而不是JSONP。

由于同源策略,可能无法使用现代浏览器访问此JSON。正如您在问题中所写,这不是您的错 - USGS根本不发送CORS标头。如果您尝试使用未实现SOP的工具发送POST请求,则可以正常工作。例如,wget的以下请求成功:

wget --post-data "json=true&site_name=model&top_left_lat=0&top_left_lon=0&bottom_right_lat=0.1&bottom_right_lon=0.1&slope_type=stable&output_types%5B%5D=jpg&output_types%5B%5D=xyz&output_types%5B%5D=grd" http://earthquake.usgs.gov/hazards/apps/vs30/vs30.php

要么他们忘了&#34; CORS标头(正如您所写),或者此API不是针对来自Web浏览器的请求而设计的,仅适用于服务器端应用程序等。

一种解决方案可能是在您自己的服务器上拥有一个代理,将代理转发给USGS服务器。如果您的服务器支持mod_proxy,请在目录的.htaccess文件中使用the ProxyPass directive

ProxyPass / http://earthquake.usgs.gov/hazards/apps/vs30/vs30.php

并将您的jQuery AJAX请求发送到此目录。

如果您不能使用.htaccess,您的服务器不支持mod_proxy等,您可以使用一个简单的PHP脚本HttpRequest编写您自己的&#34;代理&#34;:

<?php
header('Content-Type: application/json');
$req = new HttpRequest('http://earthquake.usgs.gov/hazards/apps/vs30/vs30.php', HttpRequest::METH_POST);
$req->addPostFields($_POST);
echo $req->send()->getBody();

(请注意,您应该对字段执行一些检查,捕获异常等,这只是展示它如何工作的基本示例)