一、问题的来源
我们都知道向后台传参可以使用get、put,其形式就类似于name=jyy&id=001。但是在ng中我却发现使用$http post进行异步传输的过程中后台是接收不到数据的。其实这个问题是因为请求头的缘故。在ng中默认的请求头是:“Content-Type":"application/json",也就是说传递参数是使用的就是json格式。但是后台默认的却是Content-Type': 'application/x-www-form-urlencoded'。因此在这样的情况下后台接收到的数据就会是空的。
那么为什么使用get形式就可以传参呢?在书中我发现这样的一句话:”这个键的值是一个字符串map或对象,会被转换成查询字符串追加在URL后面。如果值不是字符串,会被JSON序列化”,可以理解为在get中参数的传递是直接追加在url后面的,那么此时参数形式{"id":"1","name":"jyy"}会被转化成id=1&name=jyy追加在url后面。那么在后台中就可以直接获取到了。例如:
var app = angular.module('app',[]); app.controller('ctrl',function($scope,$q,$http){ var defer = $q.defer(); var promise = defer.promise; $http({ method: "get", params:{id:1,name:jyy}, url:"1.php" }).success(function(data){ defer.resolve(data); }); promise.then(function(data){ $scope.data = data; }) })
在后台(PHP)输入echo $_GET[id]就可以正常显示了。
那么接下来就研究怎么解决post的传值了。
二、问题的解决
1. 修改请求头
第一种方法就是在ng中修改请求头将json格式改成x-www-form-urlencoded。修改方法点击即可查看。
值得注意的是,在使用第二种方法时,可以修改put,get,post,common的传参格式。因此修改哪种方式,就只能使用这种方式才能在后台得到参数。这篇博文写到使用common进行设置可以同时使用put、get、post进行传参。但是在我的实际操作中发现对common进行修改并不能使用post进行传参,而只有设置了post的请求头才可以。
另外由于在ng中的参数都是使用json格式表达,因此需要引入jquery,使用其$.param("参数列表的json格式")进行序列化表示。
首先使用修改post请求头。具体代码如下:
var app = angular.module('app'); app.config(function($httpProvider){ $httpProvider.defaults.headers.post = { 'Content-Type': 'application/x-www-form-urlencoded' } }) app.controller('ctrl',function($scope,$resource,$q,$http){ var defer = $q.defer(); var promise = defer.promise; $http({ method: "post", data:$.param({"id":"1","name":"jyy"}), url:"1.php" }).success(function(data){ defer.resolve(data); }); promise.then(function(data){ $scope.data = data; }) })
此时在后台中(使用的是php),输入echo $_POST[id],就会显示。而debug其中显示的请求头正是我们设置的。
2.在后台进行解决
由于使用的是php,所以暂时用php的方法解决。在这个方法中,我们不修改请求头。因为get传值是正常的,那么,只要能够得到post的值就好。既然ng向后台传值了,即便是因为请求头不同,但是总会传过来什么的吧,既然能够传过来,就先获取它。这个时候使用$GLOBALS['HTTP_RAW_POST_DATA']将这个传过来的东西显示出来。那么这个$GLOBALS['HTTP_RAW_POST_DATA']是什么呢?在网上查询得知$HTTP_RAW_POST_DATA 变量包含有原始的 POST 数据。此变量仅在碰到未识别 MIME 类型的数据时产生,PHP不能识别的Content-Type类型的时候,会将http请求包中相应的数据填入变量$HTTP_RAW_POST_DATA。就是说现在这个请求头虽然是有冲突的,但是却能够显示出来。如下:
var app = angular.module('app',[]); app.controller('ctrl',function($scope,$q,$http){ var defer = $q.defer(); var promise = defer.promise; $http({ method: "post", data:{'id':'1','name':'jyy'}, url:"1.php" }).success(function(data){ defer.resolve(data); }); promise.then(function(data){ $scope.data = data; }) })
php代码:
echo $GLOBALS['HTTP_RAW_POST_DATA'];
此时显示出来的东西是:{"id":"1","name":"jyy"}。发现这个结果是正确显示了。那么直接对齐进行操作不就可以了?好吧,那就先看看是什么类型:使用gettype()得到的是string,就是说他是个json字符串。那就使用json_decode()转换,发现会报错。好吧,放弃使用这个方法。
但是此时还有另外的方法。使用file_get_contents("php://input"),这个方法中 php://input 是个可以访问请求的原始数据的只读流。 POST 请求的情况下,最好使用 php://input 来代替 $HTTP_RAW_POST_DATA,因为它不依赖于特定的 php.ini 指令。 此时这个方法就可以返回传过来的参数了。代码如下:
$a = json_decode(file_get_contents("php://input")); echo $a->id;
结果输出正确的id。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]