요청 페이로드 대신 데이터를 양식 데이터로 게시하려면 어떻게해야합니까?
아래 코드에서 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() {}
});
전달 된 $ 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 : //.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 () 등에 전달하고 원하는 결과를 얻을 수 있습니다.
또한 최고 등급의 답변은 $ .param () 함수의 페이지에 전체 jQuery를 포함시키는 것에 의존하지만 내 솔루션은 jQuery에 독립적이며 순수한 AngularJS가 준비되어 있습니다.
http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/
도움이 되었기를 바랍니다.
나는 다른 답변을 몇 가지 가지고 조금 더 깨끗하게 만들었습니다 .config()
.app.js의 angular.module 끝에이 호출을 넣으 십시오.
.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("&");
});
}]);
AngularJS v1.4.0부터는 문서 페이지$httpParamSerializer
에 나열된 규칙에 따라 모든 오브젝트를 HTTP 요청의 일부로 변환 하는 기본 제공 서비스가 있습니다 .
다음과 같이 사용할 수 있습니다 :
$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
request-object 의 속성을 수정해야합니다.
var req = {
method: 'POST',
url: 'http://example.com',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: $httpParamSerializer(formDataObj)
};
$http(req);
전역 적으로 동작을 정의 할 수 있습니다.
$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의 경우 아래 코드를 추가하여 양식 인코딩 또는 JSON으로 POST 할 수 있습니다.
//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.post(loginUrl, "userName=" + encodeURIComponent(email) +
"&password=" + encodeURIComponent(password) +
"&grant_type=password"
).success(function (data) {
//...
아래 솔루션으로 시도해 볼 수 있습니다
$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 */
});
게시 할 어댑터 서비스를 작성하십시오.
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)
})
}
})
이것과 다른 관련 자료 -AJAX 양식 제출 : AngularJS 방법을 다루는 정말 좋은 튜토리얼이 있습니다.
기본적으로 양식 데이터를 URL 인코딩 문자열로 전송하고 있음을 나타내도록 POST 요청의 헤더를 설정하고 동일한 형식으로 전송되도록 데이터를 설정해야합니다.
$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의 param () 도우미 함수가 데이터를 문자열로 직렬화하는 데 사용되지만 jQuery를 사용하지 않는 경우 수동으로 수행 할 수도 있습니다.
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 사용자의 경우 :
이것이 작동하도록 자바 스크립트에서 아무것도 변경하지 않으려는 경우 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);
Content-Type이 충분하지 않으면, 보내기 전에 양식 데이터를 URL 인코딩하십시오. $http.post(url, jQuery.param(data))
현재 AngularJS Google 그룹에서 찾은 다음 솔루션을 사용하고 있습니다.
$ http .post ( '/ echo / json /', 'json ='+ encodeURIComponent (angular.toJson (data)), { 헤더 : { '콘텐츠 유형': 'application / x-www-form-urlencoded; charset = UTF-8 ' } }). success (함수 (데이터) { $ scope.data = 데이터; });
PHP를 사용하는 경우 Request::createFromGlobals()
$ _POST가 자동으로로드되지 않으므로 Symfony 2 HTTP 구성 요소와 같은 것을 사용해야 합니다.
AngularJS는 http-request 헤더 내에서 다음과 같은 내용 유형을 수행하면서 올바르게 수행합니다.
Content-Type: application/json
나와 같은 PHP를 사용하거나 Symfony2를 사용하는 경우 http://silex.sensiolabs.org/doc/cookbook/json_request_body.html 과 같이 json 표준에 대한 서버 호환성을 간단히 확장 할 수 있습니다.
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를 기본적으로 사용하여 이러한 요청을 수행 할 수 있다는 것입니다.
완전한 답변 (각도 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) {
});
앱 구성에서-
$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'
}
이것은 직접적인 대답이 아니라 약간 다른 디자인 방향입니다.
데이터를 양식으로 게시하지 말고 서버 측 오브젝트에 직접 맵핑 할 JSON 오브젝트로 또는 REST 스타일 경로 변수를 사용하십시오.
XSRF 키를 전달하려고하므로 귀하의 경우에 적합한 옵션이 없다는 것을 알고 있습니다. 이것을 경로 변수에 매핑하는 것은 끔찍한 디자인입니다.
http://www.someexample.com/xsrf/{xsrfKey}
때문에 자연 당신은 너무 다른 경로로 XSRF 키를 전달하려는 것 /login
, /book-appointment
등 당신은 엉망 예쁜 URL 싶지 않아
흥미롭게도 객체 필드로 추가하는 것도 적절하지 않습니다. 이제 서버에 전달하는 각 json 객체에서 필드를 추가해야하기 때문에
{
appointmentId : 23,
name : 'Joe Citizen',
xsrf : '...'
}
확실히 도메인 측 객체와 직접적인 의미 론적 연관이없는 서버 측 클래스에 다른 필드를 추가하고 싶지 않습니다.
제 생각에는 xsrf 키를 전달하는 가장 좋은 방법은 HTTP 헤더를 이용하는 것입니다. 많은 xsrf 보호 서버 측 웹 프레임 워크 라이브러리가이를 지원합니다. 예를 들어 Java Spring에서는 X-CSRF-TOKEN
header를 사용하여 전달할 수 있습니다 .
JS 객체를 UI 객체에 바인딩하는 Angular의 뛰어난 기능은 양식을 모두 게시하는 연습을 없애고 대신 JSON을 게시 할 수 있음을 의미합니다. JSON은 서버 측 객체로 쉽게 역 직렬화 될 수 있으며 맵, 배열, 중첩 된 객체 등과 같은 복잡한 데이터 구조를 지원할 수 있습니다.
폼 페이로드로 배열을 어떻게 게시합니까? 아마도 이런 식으로 :
shopLocation=downtown&daysOpen=Monday&daysOpen=Tuesday&daysOpen=Wednesday
아니면 이거:
shopLocation=downtwon&daysOpen=Monday,Tuesday,Wednesday
둘 다 나쁜 디자인입니다 ..
이것은 내가 필요로하는 일입니다. 로그 인 데이터를 양식 데이터로 API에 보내야하고 Javascript Object (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 객체를 생성 할 때 "data"대신 "params"속성을 사용하는 것입니다.
$http({
method: 'POST',
url: serviceUrl + '/ClientUpdate',
params: { LangUserId: userId, clientJSON: clients[i] },
})
위의 예에서 clients [i]는 JSON 객체입니다 (어쨌든 직렬화되지 않음). "data"대신 "params"를 사용하는 경우 angular는 $ httpParamSerializer를 사용하여 객체를 직렬화합니다. https://docs.angularjs.org/api/ng/service/ $ httpParamSerializer
AngularJS $http
서비스를 사용하고 해당 post
방법을 사용 하거나 $http
기능을 구성하십시오 .
'development' 카테고리의 다른 글
C #의 일반 메소드에서 NULL을 어떻게 반환 할 수 있습니까? (0) | 2020.02.11 |
---|---|
CSS를 사용하여 div를 세로로 스크롤 가능하게 만들기 (0) | 2020.02.11 |
그런트 시계 오류-대기 중… 치명적인 오류 : ENOSPC 시계 (0) | 2020.02.11 |
.NET 4.0 프로젝트에서 .NET 2.0 혼합 모드 어셈블리를 참조하려면 어떤 '추가 구성'이 필요합니까? (0) | 2020.02.11 |
파이썬의 time.time ()은 로컬 또는 UTC 타임 스탬프를 반환합니까? (0) | 2020.02.11 |