javascript - 微信企业号:如何POST JSON数据发送消息给企业号成员
根据企业号开发者文档的发送消息接口消息数据格式,要想向企业号成员发送消息必须用POST方式将JSON数据发送到指定的包含ACCESS_TOKEN的URL。
我想实现的是每隔一段时间间隔,查询数据库之后根据查询结果向特定成员发送消息。
我在自己的linux服务器的shell上通过编写curl
命令已经可以成功地POST JSON数据,我自己的手机上也接到了信息,说明我对文档的理解和数据格式没有问题。但是这种方式必须把获取到的ACCESS_TOKEN HARD CODE到命令行中,而且TOKEN是有时限的,所以只能用来测试,不能用于生产环境中。
在生产环境中,我想的解决方案还是编写PHP/JAVASCRIPT程序来发送消息,然后在服务器端用CRON JOB来定时执行该PHP程序。但是由于对POST原理理解的不够到位,具体实现过程中碰到许多问题。
首先,如果只考虑可行性的话,能否用jQuery的ajax方法来实现呢?
在我的实验中,我先用PHP获取了正确的TOKEN,构建了URL,然后将URL值传递给了javascript 变量url,在console中尝试
$.ajax({
type: "POST",
url: url,
data: '{"touser":"Jacklyn","msgtype":"text","agentid":23,"text":{"content":"test message"}}',
success: function(){},
dataType: "json",
contentType : "application/json"
});
console返回了一个cross domain的错误,我理解因为cross domain的问题,我没法看到返回成功或失败的信息
但我的手机上也没有收到任何消息,所以发送应该是失败了。为了查看以上代码究竟发送了什么数据,我用另外一个文件来接收数据:
';
var_dump($_POST);
echo "
";
?>
但是在$.ajax返回的对象.responsText里可以看到POST的结果是
array(0) {}
如果我把AJAX方法中的datetype和contenttype去掉,在responseText中就能看到正确的数据。所以,第一个问题是,如果$.ajax发送的JSON格式的数据不能被$_POST接收到,在服务器端应如何读取发送的数据呢?
此外,我读了一些关于POST的文档,如果没有理解错的话,实际上POST传递的信息由两部分组成,一是HEADER,一是DATA;我也搜寻了一些关于如何通过PHP POST JSON数据的文章,读的不是很懂,似乎大部分文章都是说要先对HEADER进行一定程度的控制,然后才能POST JSON,这是不是意味着用javascript就无法实现呢?
最后,我用以下函数
function gotoUrl(path, params, method) {
//Null check
method = method || "post"; // Set method to post by default if not specified.
// The rest of this code assumes you are not using a library.
// It can be made less wordy if you use one.
var form = document.createElement("form");
form.setAttribute("method", method);
form.setAttribute("action", path);
//Fill the hidden form
if (typeof params === 'string') {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", 'data');
hiddenField.setAttribute("value", params);
form.appendChild(hiddenField);
}
else {
for (var key in params) {
if (params.hasOwnProperty(key)) {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", key);
if(typeof params[key] === 'object'){
hiddenField.setAttribute("value", JSON.stringify(params[key]));
}
else{
hiddenField.setAttribute("value", params[key]);
}
form.appendChild(hiddenField);
}
}
}
document.body.appendChild(form);
form.submit();
}
模拟一个表单提交数据,然后我尝试
gotoUrl(url,'{"touser":"shenkwen","msgtype":"text","agentid":23,"text":{"content":"test message"}}')
给url加上一个debug=1参数的话,可以看到postdata,以上代码的postdata是这样的:
data=%7B%22touser%22%3A%22shenkwen%22%2C%22msgtype%22%3A%22text%22%2C%22agentid%22%3A23%2C%22text%22%3A%7B%22content%22%3A%22test+message%22%7D%7D
看起来是把json字符串urlencode了,这是不是意味着在这个场合中所要求的json数据根本无法用表单方式提交?
回复内容:
根据企业号开发者文档的发送消息接口消息数据格式,要想向企业号成员发送消息必须用POST方式将JSON数据发送到指定的包含ACCESS_TOKEN的URL。
我想实现的是每隔一段时间间隔,查询数据库之后根据查询结果向特定成员发送消息。
我在自己的linux服务器的shell上通过编写curl
命令已经可以成功地POST JSON数据,我自己的手机上也接到了信息,说明我对文档的理解和数据格式没有问题。但是这种方式必须把获取到的ACCESS_TOKEN HARD CODE到命令行中,而且TOKEN是有时限的,所以只能用来测试,不能用于生产环境中。
在生产环境中,我想的解决方案还是编写PHP/JAVASCRIPT程序来发送消息,然后在服务器端用CRON JOB来定时执行该PHP程序。但是由于对POST原理理解的不够到位,具体实现过程中碰到许多问题。
首先,如果只考虑可行性的话,能否用jQuery的ajax方法来实现呢?
在我的实验中,我先用PHP获取了正确的TOKEN,构建了URL,然后将URL值传递给了javascript 变量url,在console中尝试
$.ajax({
type: "POST",
url: url,
data: '{"touser":"Jacklyn","msgtype":"text","agentid":23,"text":{"content":"test message"}}',
success: function(){},
dataType: "json",
contentType : "application/json"
});
console返回了一个cross domain的错误,我理解因为cross domain的问题,我没法看到返回成功或失败的信息
但我的手机上也没有收到任何消息,所以发送应该是失败了。为了查看以上代码究竟发送了什么数据,我用另外一个文件来接收数据:
';
var_dump($_POST);
echo "
";
?>
但是在$.ajax返回的对象.responsText里可以看到POST的结果是
array(0) {}
如果我把AJAX方法中的datetype和contenttype去掉,在responseText中就能看到正确的数据。所以,第一个问题是,如果$.ajax发送的JSON格式的数据不能被$_POST接收到,在服务器端应如何读取发送的数据呢?
此外,我读了一些关于POST的文档,如果没有理解错的话,实际上POST传递的信息由两部分组成,一是HEADER,一是DATA;我也搜寻了一些关于如何通过PHP POST JSON数据的文章,读的不是很懂,似乎大部分文章都是说要先对HEADER进行一定程度的控制,然后才能POST JSON,这是不是意味着用javascript就无法实现呢?
最后,我用以下函数
function gotoUrl(path, params, method) {
//Null check
method = method || "post"; // Set method to post by default if not specified.
// The rest of this code assumes you are not using a library.
// It can be made less wordy if you use one.
var form = document.createElement("form");
form.setAttribute("method", method);
form.setAttribute("action", path);
//Fill the hidden form
if (typeof params === 'string') {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", 'data');
hiddenField.setAttribute("value", params);
form.appendChild(hiddenField);
}
else {
for (var key in params) {
if (params.hasOwnProperty(key)) {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", key);
if(typeof params[key] === 'object'){
hiddenField.setAttribute("value", JSON.stringify(params[key]));
}
else{
hiddenField.setAttribute("value", params[key]);
}
form.appendChild(hiddenField);
}
}
}
document.body.appendChild(form);
form.submit();
}
模拟一个表单提交数据,然后我尝试
gotoUrl(url,'{"touser":"shenkwen","msgtype":"text","agentid":23,"text":{"content":"test message"}}')
给url加上一个debug=1参数的话,可以看到postdata,以上代码的postdata是这样的:
data=%7B%22touser%22%3A%22shenkwen%22%2C%22msgtype%22%3A%22text%22%2C%22agentid%22%3A23%2C%22text%22%3A%7B%22content%22%3A%22test+message%22%7D%7D
看起来是把json字符串urlencode了,这是不是意味着在这个场合中所要求的json数据根本无法用表单方式提交?
contentType也可以指定为 urlencode的。