post - 如何为表单数据, 而不是一个post数据请求负载?

  显示原文与译文双语对照的内容

在下面的代码中,AngularJS的$http 方法调用 URL,并将xsrf对象作为"请求负载"提交( 如 Chrome 调试器网络选项卡中所述) 。 jQuery $.ajax 方法执行相同的调用,但将xsrf作为"表单数据"提交。

如何让AngularJS提交xsrf作为表单数据而不是请求负载?


var url = 'http://somewhere.com/';
var xsrf = {fkey: 'xsrf key'};

$http({
 method: 'POST',
 url: url,
 data: xsrf
}).success(function () {});

$.ajax({
 type: 'POST',
 url: url,
 data: xsrf,
 dataType: 'json',
 success: function() {}
});

时间:

如果你不想在解决方案中使用 jQuery,你可以尝试。 解决方案nabbed从这里 http://stackoverflow.com 1714899/1784301


$http({
 method: 'POST',
 url: url,
 headers: {'Content-Type': 'application/x-www-form-urlencoded'},
 transformRequest: function(obj) {
 var str = [];
 for(var p in obj)
 str.push(encodeURIComponent(p) +"=" + encodeURIComponent(obj[p]));
 return str.join("&");
 },
 data: xsrf
}).success(function () {});

在你的我挑选一些其他的答案,有点接应你的吸尘器,将这份 .config() 调用做了礼物


.config(['$httpProvider', function ($httpProvider) {
//Intercept POST requests, convert to standard form encoding
 $httpProvider.defaults.headers.post["Content-Type"] ="application/x-www-form-urlencoded";
 $httpProvider.defaults.transformRequest.unshift(function (data, headersGetter) {
 var key, result = [];
 for (key in data) {
 if (data.hasOwnProperty(key)) {
 result.push(encodeURIComponent(key) +"=" + encodeURIComponent(data[key]));
 }
 }
 return result.join("&");
 });
}]);

你可以全局定义行为:


$http.defaults.headers.post["Content-Type"] ="application/x-www-form-urlencoded";

所以你不必每次都重新定义它:


$http.post("/handle/post", {
 foo:"FOO",
 bar:"BAR"
}).success(function (data, status, headers, config) {
//TODO
}).error(function (data, status, headers, config) {
//TODO
});

作为一个解决办法,你可以简单地让代码接收POST响应应用程序/json数据。 对于PHP我添加了下面的代码,允许我在form-encoded或者JSON中发布。


//handles JSON posted arguments and stuffs them into $_POST
//angular's $http makes JSON posts (not normal"form encoded")
$content_type_args = explode(';', $_SERVER['CONTENT_TYPE']);//parse content_type string
if ($content_type_args[0] == 'application/json')
 $_POST = json_decode(file_get_contents('php://input'),true);

//now continue to reference $_POST vars as usual

你可以尝试以下解决方案


$http({
 method: 'POST',
 url: url-post,
 data: data-post-object-json,
 headers: {'Content-Type': 'application/x-www-form-urlencoded'},
 transformRequest: function(obj) {
 var str = [];
 for (var key in obj) {
 if (obj[key] instanceof Array) {
 for(var idx in obj[key]){
 var subObj = obj[key][idx];
 for(var subKey in subObj){
 str.push(encodeURIComponent(key) +"[" + idx +"][" + encodeURIComponent(subKey) +"]=" + encodeURIComponent(subObj[subKey]));
 }
 }
 }
 else {
 str.push(encodeURIComponent(key) +"=" + encodeURIComponent(obj[key]));
 }
 }
 return str.join("&");
 }
 }).success(function(response) {
/* Do something */
 });

对于Symfony2用户:

如果你不想更改javascript中的任何内容,你可以在symfony应用程序中进行这些修改:

创建一个扩展SymfonyComponentHttpFoundationRequest类的类:


<?php

namespace AcmeTestMyRequest;

use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationParameterBag;

class MyRequest extends Request{


/**
* Override and extend the createFromGlobals function.
* 
* 
*
* @return Request A new request
*
* @api
*/
public static function createFromGlobals()
{
//Get what we would get from the parent
 $request = parent::createFromGlobals();

//Add the handling for 'application/json' content type.
 if(0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/json')){

//The json is in the content
 $cont = $request->getContent();

 $json = json_decode($cont);

//ParameterBag must be an Array.
 if(is_object($json)) {
 $json = (array) $json;
 }
 $request->request = new ParameterBag($json);

}

return $request;

}

}

现在使用 app_dev.php 中的类( 或者你使用的任何索引文件)


//web/app_dev.php

$kernel = new AppKernel('dev', true);
//$kernel->loadClassCache();
$request = ForumBundleRequest::createFromGlobals();

//use your class instead
//$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

有一个非常好的教程,可以通过这个和其他相关的内容- 提交AJAX表单: AngularJS的方式 。

基本上,你需要设置POST请求的头部,以表明你正在将表单数据作为URL编码字符串发送,并将数据设置为发送的格式相同


$http({
 method : 'POST',
 url : 'url',
 data : $.param(xsrf),//pass in data as strings
 headers : { 'Content-Type': 'application/x-www-form-urlencoded' }//set the headers so angular passing info as form data (not request payload)
});

使用jquery,请注意,jQuery的param() helper 函数在这里被用于将数据转换为一个字符串,但可以手动执行这里操作为做好如果 not. serialising

...