Внимание: Ниже приведены более качественные ответы. Этот ответ был написан в 2010 году, и с тех пор появились новые и лучшие решения.
blockquote>
function formatDate(date) { var monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; var day = date.getDate(); var monthIndex = date.getMonth(); var year = date.getFullYear(); return day + ' ' + monthNames[monthIndex] + ' ' + year; } console.log(formatDate(new Date())); // show current date-time in console
Вы можете отредактировать массив
monthNames
, чтобы использовать Jan, Feb, Mar , и т.д ..
Следующая строка должна быть добавлена к передаваемому объекту $ http:
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
И переданные данные должны быть преобразованы в строку с кодировкой URL:
> $.param({fkey: "key"})
'fkey=key'
Итак, у вас есть что-то вроде:
$http({
method: 'POST',
url: url,
data: $.param({fkey: "key"}),
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
})
От: https://groups.google.com/forum/#!msg/angular/5nAedJ1LyO0/4Vj_72EZcDsJ
Чтобы использовать новые сервисы, добавленные с помощью AngularJS V1.4, см.
Если вы не хотите использовать jQuery в решении, вы можете попробовать это. Решение, взятое здесь https://stackoverflow.com/a/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 () {});
Продолжающаяся путаница вокруг этой проблемы вдохновила меня написать сообщение в блоге об этом. Решение, которое я предлагаю в этом сообщении, лучше, чем ваше текущее решение с наивысшим рейтингом, поскольку оно не ограничивает вас параметризацией вашего объекта данных за вызовы службы $ http; т.е. с моим решением вы можете просто продолжать передавать фактические объекты данных в $ http.post () и т. д. и все еще добиваться желаемого результата.
Кроме того, самый рейтинговый ответ основывается на включении полного jQuery на странице для функции $ .param (), тогда как мое решение jQuery агностик, чистый AngularJS готов.
http://victorblog.com/2012/12/20/make-angularjs -http-service-behave-like-jquery-ajax /
Надеюсь, это поможет.
В настоящее время я использую следующее решение I найдено в группе google AngularJS.
$http .post('/echo/json/', 'json=' + encodeURIComponent(angular.toJson(data)), { headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' } }).success(function(data) { $scope.data = data; });
Обратите внимание, что если вы используете PHP, вам нужно будет используйте что-то вроде компонента HTTP Request::createFromGlobals()
Symfony 2 HTTP, чтобы прочитать это, поскольку $ _POST не будет автоматически загружаться с ним.
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
Пожалуйста, проверьте! https://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs
Для пользователей Symfony2:
Если вы не хотите что-то менять в своем javascript, чтобы это сработало, вы можете сделать эти изменения в своем приложении symfony:
Создать класс который расширяет класс Symfony \ Component \ HttpFoundation\request:
<?php
namespace Acme\Test\MyRequest;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\ParameterBag;
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);
Это не прямой ответ, а немного другое направление проектирования:
Не отправляйте данные в виде формы, но поскольку объект JSON должен быть непосредственно сопоставлен с серверным объектом, или использовать переменную пути пути REST
Теперь я не знаю, что ни один из вариантов не подходит для вашего случая, поскольку вы пытаетесь передать ключ XSRF. Отображение его в переменной пути, как это, является ужасным дизайном:
http://www.someexample.com/xsrf/{xsrfKey}
Поскольку по своей природе вы хотели бы передать ключ xsrf другому пути, /login
, /book-appointment
и т. Д., И вы не 't хотите испортить ваш симпатичный URL
Интересно добавить его как поле объекта тоже не подходит, потому что теперь на каждом из json-объектов вы переходите на сервер, вы должны добавить поле
{
appointmentId : 23,
name : 'Joe Citizen',
xsrf : '...'
}
Вы, конечно, не хотите добавлять другое поле в свой серверный класс, который не имеет прямой семантической связи с объектом домена.
На мой взгляд, лучший способ передать ваш Ключ xsrf через HTTP-заголовок. Это поддерживает многостраничная веб-библиотека защиты xsrf. Например, в Java Spring вы можете передать его с помощью заголовка X-CSRF-TOKEN
.
Отличная способность Angular связывать объект JS с объектом пользовательского интерфейса означает, что мы можем избавиться от практики публикации сформировать все вместе и вместо этого разместить JSON. JSON можно легко де-сериализовать на серверный объект и поддерживать сложные структуры данных, такие как карта, массивы, вложенные объекты и т. Д.
Как вы размещаете массив в форме полезной нагрузки? Может быть, так:
shopLocation=downtown&daysOpen=Monday&daysOpen=Tuesday&daysOpen=Wednesday
или это:
shopLocation=downtwon&daysOpen=Monday,Tuesday,Wednesday
Оба плохой дизайн ..
В качестве обходного пути вы можете просто заставить код, получающий POST, отвечать на данные приложения / json. Для PHP я добавил код ниже, разрешив мне POST для него либо в форме, либо в 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
Я взял несколько других ответов и сделал что-то немного более чистым, поместите этот вызов .config()
в конец вашего angular.module в вашем приложении app.js:
.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 = [];
if (typeof data === "string")
return data;
for (key in data) {
if (data.hasOwnProperty(key))
result.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
}
return result.join("&");
});
}]);
Просто установить Content-Type недостаточно, url кодирует данные формы перед отправкой. $http.post(url, jQuery.param(data))
AngularJS делает это правильно, поскольку делает следующий контент-тип внутри заголовка http-запроса:
Content-Type: application/json
Если вы собираетесь с php, как я, или даже с Symfony2, вы можете просто расширить ваша совместимость с сервером для стандартного json, как описано здесь: http://silex.sensiolabs.org/doc/cookbook/json_request_body.html
Способ Symfony2 (например, внутри вашего DefaultController ):
$request = $this->getRequest();
if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
$data = json_decode($request->getContent(), true);
$request->request->replace(is_array($data) ? $data : array());
}
var_dump($request->request->all());
Преимущество заключалось бы в том, что вам не нужно использовать параметр jQuery, и вы можете использовать AngularJS свой собственный способ выполнения таких запросов.
Начиная с версии AngularJS v1.4.0 существует встроенная служба $httpParamSerializer
, которая преобразует любой объект в часть HTTP-запроса в соответствии с правилами, указанными на странице docs .
Его можно использовать следующим образом:
$http.post('http://example.com', $httpParamSerializer(formDataObj)).
success(function(data){/* response status 200-299 */}).
error(function(data){/* response status 400-999 */});
Помните, что для правильной записи формы заголовок Content-Type
должен быть изменен. Чтобы сделать это глобально для всех запросов POST, этот код (взятый из полуответчика Albireo) можно использовать:
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
Чтобы сделать это только для текущей записи, свойство headers
запроса -объект необходимо изменить:
var req = {
method: 'POST',
url: 'http://example.com',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: $httpParamSerializer(formDataObj)
};
$http(req);
Создайте службу адаптера для сообщения:
services.service('Http', function ($http) {
var self = this
this.post = function (url, data) {
return $http({
method: 'POST',
url: url,
data: $.param(data),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
}
})
Используйте его в своих контроллерах или что-то еще:
ctrls.controller('PersonCtrl', function (Http /* our service */) {
var self = this
self.user = {name: "Ozgur", eMail: null}
self.register = function () {
Http.post('/user/register', self.user).then(function (r) {
//response
console.log(r)
})
}
})
Единственный тон, который вам нужно изменить, это использовать свойство «params», а не «data», когда вы создаете свой объект $ http:
$http({
method: 'POST',
url: serviceUrl + '/ClientUpdate',
params: { LangUserId: userId, clientJSON: clients[i] },
})
. В примере выше клиенты [i] просто Объект JSON (не сериализованный каким-либо образом). Если вы используете «params», а не «data», угловое будет сериализовать объект для вас, используя $ httpParamSerializer: https://docs.angularjs.org/api/ng/service/ $ httpParamSerializer
Есть действительно хороший учебник, который рассказывает об этом и других связанных вещах - Отправка форм AJAX: Угловой путь .
В принципе, вам нужно установить заголовок запроса 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)
});
Обратите внимание, что здесь используется вспомогательная функция param () jQuery для сериализации данных в строку, но вы также можете сделать это вручную, если не используете jQuery.
Полный ответ (с углового 1.4). Вам нужно включить зависимость $ httpParamSerializer
var res = $resource(serverUrl + 'Token', { }, {
save: { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
});
res.save({ }, $httpParamSerializer({ param1: 'sdsd', param2: 'sdsd' }), function (response) {
}, function (error) {
});
Эти ответы выглядят как безумный излишний, иногда простой просто:
$http.post(loginUrl, "userName=" + encodeURIComponent(email) +
"&password=" + encodeURIComponent(password) +
"&grant_type=password"
).success(function (data) {
//...
Используйте службу AngularJS $http
и используйте свой метод post
или настройте функцию $http
.
Это то, что я делаю для своих нужд. Где мне нужно отправить данные входа в API в виде данных формы, а объект Javascript (userData) автоматически преобразуется в URL-кодированные данные
var deferred = $q.defer();
$http({
method: 'POST',
url: apiserver + '/authenticate',
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: userData
}).success(function (response) {
//logics
deferred.resolve(response);
}).error(function (err, status) {
deferred.reject(err);
});
Это как мои Userdata
var userData = {
grant_type: 'password',
username: loginData.userName,
password: loginData.password
}
Вы можете попробовать с помощью решения ниже
$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 */
});
В вашем приложении config -
$httpProvider.defaults.transformRequest = function (data) {
if (data === undefined)
return data;
var clonedData = $.extend(true, {}, data);
for (var property in clonedData)
if (property.substr(0, 1) == '$')
delete clonedData[property];
return $.param(clonedData);
};
С запросом вашего ресурса -
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
Вы можете определить поведение по всему миру:
$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
});