请选择 进入手机版 | 继续访问电脑版
 找回密码
 立即注册

QQ登录

只需一步,快速开始

guoqp
金牌服务用户   /  发表于:2023-9-13 14:59  /   查看:135  /  回复:12
10金币
服务端命令参数如下图


我在客户端POST的时候是这样写的(先生成JSON字符串,再将字符串转成JSON对象,再POST)
  1.     let jsonstring = '{';
  2.     jsonstring += '"日期":"' + rq + '",';
  3.     jsonstring += '"经办人":"' + jbr +'",';
  4.     jsonstring += '"项目编号":"' + xmbh + '",';
  5.     jsonstring += '"WBS":"' + wbs + '",';
  6.     jsonstring += '"合同金额":' + htje + ',';
  7.     jsonstring += '"客户编码":"' + khbh + '",';
  8.     jsonstring += '"销售订单号":"' + ddh + '",';
  9.     jsonstring += '"业主单位":"' + yzdw + '",';
  10.     jsonstring += '"监理单位":"' + jldw + '",';
  11.     jsonstring += '"项目经理":"' + xmjl + '",';
  12.     jsonstring += '"项目管理负责人":"' + '",';
  13.     jsonstring += '"进度数据":[';
  14.     var rowArr = WfForm.getDetailAllRowIndexStr("detail_1").split(",");
  15.     for(var i=0; i<rowArr.length; i++){
  16.         var rowIndex = rowArr[i];
  17.         if(rowIndex !== ""){
  18.             let jdmc = WfForm.getFieldValue("field18563_"+rowIndex);
  19.             let jdje = WfForm.getFieldValue("field18574_"+rowIndex);
  20.             let qqyqrjd = parseFloat(WfForm.getFieldValue("field18564_"+rowIndex));
  21.             if(isNaN(qqyqrjd)){qqyqrjd = 0;}
  22.             let bqqrjd = parseFloat(WfForm.getFieldValue("field18565_"+rowIndex));
  23.             if(isNaN(bqqrjd)){bqqrjd = 0;}
  24.             let ljqrjd = parseFloat(WfForm.getFieldValue("field18566_"+rowIndex));
  25.             if(isNaN(ljqrjd)){ljqrjd = 0;}
  26.             let bz = WfForm.getFieldValue("field18567");
  27.             jsonstring += '{';
  28.             jsonstring += '"阶段名称":"' + jdmc + '",';
  29.             jsonstring += '"阶段金额":' + jdje + ',';
  30.             jsonstring += '"前期已确认进度":' + qqyqrjd + ',';
  31.             jsonstring += '"本期确认进度":' + bqqrjd + ',';
  32.             jsonstring += '"累计确认进度":' + ljqrjd + ',';
  33.             jsonstring += '"备注":"' + bz + '"';
  34.             jsonstring += '}';
  35.             if(i < rowArr.length - 1){
  36.               jsonstring += ',';
  37.             }
  38.         }
  39.     }
  40.     jsonstring += ']}';
  41.     console.log(jsonstring);
  42.     let jsonObject = JSON.parse(jsonstring);
  43.     $.ajax({
  44.       type:"post",
  45.       dataType: "json",
  46.       async:false,
  47.       url:"http://" + server + "/pm/ServerCommand/ProjectScheduleInsert",
  48.       data:jsonObject,
  49.       success:function(result){
  50.         console.log(result.msg);
  51.         if(result.msg=="ok"){
  52.           callback();
  53.         }else{
  54.           alert(result.msg);
  55.         }
  56.       },
  57.       error: function() {  
  58.         alert('数据同步出错,请联系系统管理员');  
  59.       }
  60.     });
复制代码
但一提交就出错,我在服务端是能收到这个请求的,只是出现了如下图错误

我请求的JSON字符串也没有问题啊,我也一起贴出来
  1. {"日期":"2023-09-13","经办人":"张玄","项目编号":"22036","WBS":"S-20221990036","合同金额":228,"客户编码":"10173399","销售订单号":"","业主单位":"四川澳晟新材料科技有限责任公司","监理单位":"","项目经理":"赵宇","项目管理负责人":"","进度数据":[{"阶段名称":"第1阶段","阶段金额":228.000000,"前期已确认进度":0.4,"本期确认进度":0.35,"累计确认进度":0.75,"备注":""}]}
复制代码
不知道为啥这个进度数据明明上边都解析出来的,但下边又提示好像说是不存在,有知道这个问题如何解决的大佬没?
附件: 您需要 登录 才可以下载或查看,没有帐号?立即注册

最佳答案

查看完整内容

您好,活字格服务端命令目前参数支持接受的类型(Content-Type)为:x-www-form-urlencoded 和 application/json。 针对上面两个请求参数类型,这边分别对跨域和 key 不存在报错问题的原因进行解释。 这里我们有一个服务端命令,服务端命令有 param1 和 param2 两个参数,其中 param2 参数为数组类型,如下: x-www-form-urlencoded 出现 Key 不存在的原因有两个,都和传输的参数类型有关。如果是使用 Ajax 发起前端 ...

12 个回复

倒序浏览
最佳答案
最佳答案
Simon.Sun
超级版主   /  发表于:2023-9-13 14:59:10
来自 7#
您好,活字格服务端命令目前参数支持接受的类型(Content-Type)为:x-www-form-urlencoded 和 application/json。
针对上面两个请求参数类型,这边分别对跨域和 key 不存在报错问题的原因进行解释。

这里我们有一个服务端命令,服务端命令有 param1 和 param2 两个参数,其中 param2 参数为数组类型,如下:


x-www-form-urlencoded


出现 Key 不存在的原因有两个,都和传输的参数类型有关。如果是使用 Ajax 发起前端请求,需要保证前端传输的请求参数是一个对象,而非 JSON 字符串。否则就会因为我们传输的参数是一个完整的字符串,是没有 key 的(这个我们可以在浏览器控制台观察到)。比如:


所以当请求参数类型为 x-www-form-urlencoded 时,我们需要传输对象,而非字符串,但是我们传输的对象的属性为数组类型,也会存在问题,比如:

可以看到数组类型 param2 在传输时 key 类似于 param2[0] 这样的格式,会导致服务端命令找不到 param2 参数。
所以如果我们要传递数组时,在使用 x-www-form-urlencoded 格式,可以把传输的数组作为一个完成的字符串传递,然后服务端命令里发序列化,去处理数组,比如:



关于跨域 x-www-form-urlencoded 属于简单请求关于简单请求和复杂请求的定义,可以看:跨源资源共享(CORS) - HTTP | MDN (mozilla.org)
简单请求在发起跨域请求时不会发 OPTIONS 预检验请求,结合豪豪大佬的处理跨域的服务端命令可以从服务端解决跨域问题。

application/json

当请求类型为 application/json 时,请求参数需要传递 JSON 字符串,比如:

这时候如果能保证传递参数的 key 和服务端命令参数名能够匹配上,是不会出现 key 不存在问题的。

关于跨域,application/json 是个复杂请求,在服务端发起跨域请求时会进行 OPTIONS 预检验请求,但是活字格服务端命令不支持 OPTIONS 请求,所以这个从服务端去出发是解决不了跨域问题的。

总结一下,目前您那边在调用服务端命令,且要规避跨域问题,需要保证请求参数类型为 x-www-form-urlencoded,且数组类型的参数处理值为一个字符串,服务端名再处理数组时,反序列化这个字符串再处理数组,这样可以规避 key 不存在问题。同时结合豪豪大佬的跨域服务端命令来规避跨域问题。

关于 Postman 能正常调用,而不会跨域是因为跨域是浏览器策略,postman 作为客户端发起请求不受此影响。






本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 使用道具 举报
逛逛逛
金牌服务用户   /  发表于:2023-9-13 16:19:52
2#
不会是匿名用户的权限问题吧
回复 使用道具 举报
Tony.Fu
超级版主   /  发表于:2023-9-13 17:30:52
3#
本帖最后由 Tony.Fu 于 2023-9-13 17:39 编辑

guoqp您好,我尝试本地做了个类似的项目,用post请求调用是正常的

您参考下我这个项目,如果仍有问题能否提供个fgcc项目demo我们看看?
我这个是在9.0.6中测试的,您也可以确认下是否是版本问题

post请求:
  1. {
  2.     "名称":"a",
  3.     "详情":[{"列1":"1","列2":228.0000000,"列3":3},{"列1":"4","列2":5.0,"列3":"6"}]
  4. }
复制代码
\



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 使用道具 举报
guoqp
金牌服务用户   /  发表于:2023-9-13 18:36:02
4#
Tony.Fu 发表于 2023-9-13 17:30
guoqp您好,我尝试本地做了个类似的项目,用post请求调用是正常的

您参考下我这个项目,如果仍有问题能 ...

提示那个错误是啥意思啊?我理解是json对象里找不到那个属性?但从解析来看明明有啊
回复 使用道具 举报
guoqp
金牌服务用户   /  发表于:2023-9-13 22:07:46
5#
Tony.Fu 发表于 2023-9-13 17:30
guoqp您好,我尝试本地做了个类似的项目,用post请求调用是正常的

您参考下我这个项目,如果仍有问题能 ...

是这么个情况,用POST工具测试都OK,可能因为调用脚本的网页域名来自于互联网,所以我一提交就会报一个跨域错误,但服务器能收到请求,只是到参数解析那步就直接报错了


我在接口上使用了允许跨域命令,应该是支持跨域的才对啊,因为我其他命令都是OK的,就这个命令不行

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 使用道具 举报
guoqp
金牌服务用户   /  发表于:2023-9-13 22:08:57
6#
Tony.Fu 发表于 2023-9-13 17:30
guoqp您好,我尝试本地做了个类似的项目,用post请求调用是正常的

您参考下我这个项目,如果仍有问题能 ...

这是我用POST工具测试都OK的

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 使用道具 举报
guoqp
金牌服务用户   /  发表于:2023-9-14 16:48:05
8#
Simon.Sun 发表于 2023-9-14 12:31
您好,活字格服务端命令目前参数支持接受的类型(Content-Type)为:x-www-form-urlencoded 和 application ...

使用你说的方法:将数组改为字符串,再在命令中反序列化,这个是可以的(唯一缺点就是要将\"替换成"后才能反序列化)
这里我就纳闷了,在浏览器中为啥参数值为字符串就可以,为数组就会出现找不到KEY的情况,这是什么道理?
但在POST工具中又可以直接使用数组对象作为参数值,是因为跨域问题么?
回复 使用道具 举报
Simon.Sun
超级版主   /  发表于:2023-9-14 17:06:44
9#
POST 工具中您使用的是 application/json 作为请求参数的类型,也就是我上面说的第二种情况。这时候传递 JSON 对象时可以的。但是当请求报文格式为 x-www-form-urlencoded 时,如果在 ajax 中传递的熟悉值为数组,参数的形式就为 param2[0]=xxx,它的 key 为 param2[0],不是 param2,就会出现 param2 key 找不到的错误。
回复 使用道具 举报
guoqp
金牌服务用户   /  发表于:2023-9-14 17:38:48
10#
Simon.Sun 发表于 2023-9-13 14:59
您好,活字格服务端命令目前参数支持接受的类型(Content-Type)为:x-www-form-urlencoded 和 application ...

结合你说的这个我作了另一个测试,提交仍使用JSON对象,但增加了内容类型参数


也使用了豪豪大佬的跨域插件

但浏览器上一提交就报这个错

服务器端日志则报这个错

感觉这个有点像是JSON类型的跨域问题

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 立即注册
返回顶部