所以我尝试使用$ .ajax()调用将数据提交到API端点。我已经验证我可以使用curl
命令进行POST,格式如下:
curl -X POST -H "Content-Type: application/json" -d "{\"uname\":\"myusername2\",\"emailAddr\":\"user2@ex.com\"}" <url to my API endpoint>
curl
命令返回一个空的JSON响应(看起来像{}
),我的数据被放入数据库(这是我配置的API网关端点)。
但是,当我尝试使用$.ajax()
命令执行此操作时,该命令被编程为在填写表单数据后单击按钮时触发,我无法使其工作。
var obj = new Object();
obj.uname = $uname;
obj.emailAddr = $email;
var stringedObj = JSON.stringify(obj);
alert("stringified: " + stringedObj);
$.ajax({
url: '<same url as in curl>',
type: 'POST',
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify(obj),
success: function(data) {
alert(JSON.stringify(data));
},
error: function(e) {
alert("failed" + JSON.stringify(e));
}
});
每当我运行此命令时,我都可以从第一条警报消息中看到我的数据已正确字符串化。但是,我总是得到一条如下所示的错误消息:
failed{"readyState":0,"responseText":"","status":0,"statusText":"error"}
我想知道是否可以获得更详细的错误响应。另外,我尝试过使用parseData: false
和crossdomain: true
。再一次,它在我使用curl时有效,所以我很确定这不是API网关配置问题。
感谢您的帮助!
编辑:我从下面的评论中了解到了javascript控制台。现在我发现这是由于CORS没有启用。我在AWS Api Gateway中启用了CORS,等待完成,然后将我的请求更改为:
$.ajax({
url: '<my url>',
type: 'POST',
data: JSON.stringify(obj),
dataType: 'json',
crossDomain: true,
success: function(data) {
alert(JSON.stringify(data));
},
error: function(e) {
alert("failed" + JSON.stringify(e));
}
});
我在javascript控制台中得到了关于需要CORS的相同响应。 Other threads on CORS have shown以此为例。我想知道我是否需要自定义标头,虽然我尝试添加headers: { "Access-Control-Allow-Origin": "*" }
但仍然从javascript控制台得到相同的响应:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://k6i6wk8487.execute-api.us-west-2.amazonaws.com/prod/comments. (Reason: CORS header 'Access-Control-Allow-Origin' missing).
答案 0 :(得分:2)
想出来,在将其更新为启用CORS后,我没有在AWS API Gateway中点击'deploy'。卫生署!感谢所有帮助过的人。这是我最后的ajax电话:
$.ajax({
url: $invokeUrl,
type: 'POST',
data: JSON.stringify(obj),
dataType: 'json',
crossDomain: true,
contentType: 'application/json',
success: function(data) {
alert(JSON.stringify(data));
},
error: function(e) {
alert("failed" + JSON.stringify(e));
感谢所有帮助过的人,如果您使用API网关遇到此问题,请告诉我,我会尽力提供帮助。
答案 1 :(得分:0)
您可以使用JSONP技术发出请求:
<script>
function parseJSONP(response) {
// Process the JSON response here.
}
function loadScript(url, data, callback) {
script = document.createElement('script');
document.getElementsByTagName('head')[0].appendChild(script);
script.src = url
+'?callback='+callback
+'&data='+encodeURIComponent(JSON.stringify(data))
;
}
loadScript('http://yourdifferentdomain', yourdata, 'parseJSONP');
</script>
您可能需要调整远程服务以接受和解码URL中的数据参数。
另一种方法,可能更好,是将外部URL包装为参数,将POST数据的一部分包装到本地CURL,让服务器获取其他域的响应,并将其放回到响应中同一个域名。按照你的例子:
JS:
var curlBridge = 'http://samedomain/curl-resource/';
var remoteURL = 'http://otherdomain/target-resource/';
var obj = {}; // Your data to cross-domain post.
$.ajax({
url: curlBridge,
type: 'POST',
data: JSON.stringify({
"url": remoteURL,
"headers": null, // Headers you may want to pass
"post": obj
}),
dataType: 'json',
crossDomain: true,
contentType: 'application/json',
success: function(data) {
alert(JSON.stringify(data));
},
error: function(ev) {
alert("failed" + JSON.stringify(ev));
}
});
PHP:
<?php
function callUrl($url, $post = null, $headers = null) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 60000); // DEF 1000*60... // Hide/Show
$post_str = "";
if (is_array($post)) {
if (count($post)) {
foreach ($post as $key => $val) {
if (is_array($val) && count($val)) {$val = json_encode($val);}
$post_str .= "&".$key."=".$val;
}
if ($post_str[0] == "&") {$post_str = substr($post_str, 1);}
}
} else {$post_str = "".$post;}
if ($post_str || is_array($post)) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_str);
}
if (is_array($headers) && count($headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
} else {$headers = array();}
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
$input = array_merge($_GET, $_POST);
echo callUrl($input['url'], $input['post'], $input['headers']);