응용 프로그램/x-www-form-urlencoded를 사용한 POST 요청
백엔드 개발자는 POST 요청 시 다음과 같은 지시를 내렸습니다.
- 경로: {url}/{app_name/{controller}/{action}
- 컨트롤러와 액션은 작은 캡으로 해야 합니다.
- API 테스트 링크: http:******************
- 요청은 POST Method를 사용해야 합니다.
- 매개 변수는 요청 컨텐츠 본문(FormUrlEncodedContent)을 통해 전달되어야 합니다.
- 매개 변수는 json 형식이어야 합니다.
- 파라미터는 키에 민감합니다.
프로토콜에서 5번을 사용한 경험이 없어서 코드를 검색하여 종료했습니다.
-(id)initWithURLString:(NSString *)URLString withHTTPMEthod:(NSString *)method withHTTPBody:(NSDictionary *)body {
_URLString = URLString;
HTTPMethod = method;
HTTPBody = body;
//set error message
errorMessage = @"Can't connect to server at this moment. Try again later";
errorTitle = @"Connection Error";
return self;
}
-(void)fireConnectionRequest {
NSOperationQueue *mainQueue = [[NSOperationQueue alloc] init];
[mainQueue setMaxConcurrentOperationCount:5];
NSError *error = Nil;
NSURL *url = [NSURL URLWithString:_URLString];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
NSData *sendData = [NSJSONSerialization dataWithJSONObject:HTTPBody options:NSJSONWritingPrettyPrinted error:&error];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setHTTPBody: sendData];
[NSURLConnection connectionWithRequest:request delegate:self];
NSString *jsonString = [[NSString alloc]initWithData:sendData encoding:NSUTF8StringEncoding];
//fire URL connectiion request
[NSURLConnection sendAsynchronousRequest:request queue:mainQueue completionHandler:^(NSURLResponse *response, NSData *responseData, NSError *error) {
//get the return message and transform to dictionary
NSString *data = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
returnMessage = [NSJSONSerialization JSONObjectWithData: [data dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error:&error];
//check return message
if (!error) {
[delegate returnMessageForTag:self.tag];
}
else {
[delegate returnErrorMessageForTag:self.tag];
}
}];
}
JSON으로 포맷된 사전을 전달했습니다. 그는 제가 올바른 데이터를 전달할 수 있었다는 것에 동의했습니다.그리고 API에 접속할 수 있었지만, 등록 데이터를 송신하려고 하면 항상 "FAILED"가 반환됩니다.연결에는 문제가 없지만 데이터 전송에 실패했습니다.
같은 API를 사용하는 안드로이드 개발자는 문제없지만 iOS에 익숙하지 않아 도움을 주지 못했습니다.
제가 무엇을 빠뜨리고 있나요?
이 코드와 같이 시도합니다.
목표 C
NSString *post =[NSString stringWithFormat:@"AgencyId=1&UserId=1&Type=1&Date=%@&Time=%@&Coords=%@&Image=h32979`7~U@)01123737373773&SeverityLevel=2",strDateLocal,strDateTime,dict];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d",[postData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://google/places"]]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
NSError *error;
NSURLResponse *response;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *str=[[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
스위프트 2.2
var post = "AgencyId=1&UserId=1&Type=1&Date=\(strDateLocal)&Time=\(strDateTime)&Coords=\(dict)&Image=h32979`7~U@)01123737373773&SeverityLevel=2"
var postData = post.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)!
var postLength = "\(postData.length)"
var request = NSMutableURLRequest()
request.URL = NSURL(string: "http://google/places")!
request.HTTPMethod = "POST"
request.setValue(postLength, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.HTTPBody = postData
NSError * error
NSURLResponse * response
var urlData = try! NSURLConnection.sendSynchronousRequest(request, returningResponse: response)!
var str = String(data: urlData, encoding: NSUTF8StringEncoding)
Swift 3.0
let jsonData = try? JSONSerialization.data(withJSONObject: kParameters)
let url: URL = URL(string: "Add Your API URL HERE")!
print(url)
var request: URLRequest = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = jsonData
request.setValue(Constant.UserDefaults.object(forKey: "Authorization") as! String?, forHTTPHeaderField: "Authorization")
request.setValue(Constant.kAppContentType, forHTTPHeaderField: "Content-Type")
request.setValue(Constant.UserAgentFormat(), forHTTPHeaderField: "User-Agent")
let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
if data != nil {
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! NSDictionary
print(json)
} catch let error as NSError {
print(error)
}
} else {
let emptyDict = NSDictionary()
}
})
task.resume()
스위프트 4
let headers = [
"Content-Type": "application/x-www-form-urlencoded"
]
let postData = NSMutableData(data: "UserID=351".data(using: String.Encoding.utf8)!)
let request = NSMutableURLRequest(url: NSURL(string: "Add Your URL Here")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error!)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse!)
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments)
print(json)
} catch {
print(error)
}
}
})
dataTask.resume()
알라모파이어
Alamofire.request("Add Your URL Here",method: .post, parameters: ["CategoryId": "15"])
.validate(contentType: ["application/x-www-form-urlencoded"])
.responseJSON { (response) in
print(response.result.value)
}
이 코드가 당신에게 도움이 되길 바랍니다.
스위프트 4
let params = ["password":873311,"username":"jadon","client_id":"a793fb82-c978-11e9-a32f-2a2ae2dbcce4"]
let jsonString = params.reduce("") { "\($0)\($1.0)=\($1.1)&" }.dropLast()
let jsonData = jsonString.data(using: .utf8, allowLossyConversion: false)!
urlRequest.addValue("application/x-www-form-urlencoded", forHTTPHeaderField:"Content-Type")
urlRequest.httpBody = jsonData
@fatihyildizan
당신의 답변에 직접 코멘트를 달기에는 충분한 평판이 없기 때문에 이 답변이 필요합니다.
스위프트 1.2
let myParams = "username=user1&password=12345"
let postData = myParams.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)
let postLength = String(format: "%d", postData!.length)
var myRequest = NSMutableURLRequest(URL: self.url)
myRequest.HTTPMethod = "POST"
myRequest.setValue(postLength, forHTTPHeaderField: "Content-Length")
myRequest.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
myRequest.HTTPBody = postData
var response: AutoreleasingUnsafeMutablePointer<NSURLResponse?> = nil
위의 코드는 제 경우 정상적으로 작동합니다.
Swift는 URL-%-encoding 기능을 제공하지만 첫 번째 코멘트에서 @nolanw가 지적한 것과 완전히 일치하는 것은 아닙니다.첫 번째 질문의 스텝5에서는 키와 값의 페어가 어떤 구조에서 확립되면 간단하고 간단한 부호화 대체 방법(Swift 4.2)을 다음에 나타냅니다.
var urlParser = URLComponents()
urlParser.queryItems = [
URLQueryItem(name: "name", value: "Tim Tebow"),
URLQueryItem(name: "desc", value: "Gators' QB")
]
let httpBodyString = urlParser.percentEncodedQuery
Xcode 플레이그라운드에 붙여넣고 추가한다.print(httpBodyString!)
출력에는 다음이 표시됩니다.
name=Tim%20Tebow&desc=Gators'%20QB
참고: 이것은 기본 폼 값의 백분율 인코딩 세트(즉, 이진 데이터나 멀티 파트가 아님)에 대한 것입니다.
이 버전에서는 파라미터의 인코딩과 공백의 '+' 치환을 처리합니다.
extension String {
static let formUrlencodedAllowedCharacters =
CharacterSet(charactersIn: "0123456789" +
"abcdefghijklmnopqrstuvwxyz" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"-._* ")
public func formUrlencoded() -> String {
let encoded = addingPercentEncoding(withAllowedCharacters: String.formUrlencodedAllowedCharacters)
return encoded?.replacingOccurrences(of: " ", with: "+") ?? ""
}
}
class HTTPUtils {
public class func formUrlencode(_ values: [String: String]) -> String {
return values.map { key, value in
return "\(key.formUrlencoded())=\(value.formUrlencoded())"
}.joined(separator: "&")
}
}
let headers = [
"content-type": "application/x-www-form-urlencoded; charset=utf-8"
]
let body = HTTPUtils.formUrlencode([
"field": "value"
])
var request = try URLRequest(url: url, method: .post, headers: headers)
request.httpBody = body.data(using: .utf8)
URLSession.shared.dataTask(with: request, completionHandler: { ... }).resume()
Swift 3에서 jsonData =를 사용해 보시겠습니까?JSON Serialization.data(JSONObject: kParameters 사용)가 제대로 작동하지 않아 Alamo Fire 솔루션을 복사해야 했습니다.
let body2 = ["username": "au@gmail.com",
"password": "111",
"client_secret":"7E",
"grant_type":"password"]
let data : Data = query(body2).data(using: .utf8, allowLossyConversion: false)!
var request : URLRequest = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField:"Content-Type");
request.setValue(NSLocalizedString("lang", comment: ""), forHTTPHeaderField:"Accept-Language");
request.httpBody = data
do {...}
}
public func queryComponents(fromKey key: String, value: Any) -> [(String, String)] {
var components: [(String, String)] = []
if let dictionary = value as? [String: Any] {
for (nestedKey, value) in dictionary {
components += queryComponents(fromKey: "\(key)[\(nestedKey)]", value: value)
}
} else if let array = value as? [Any] {
for value in array {
components += queryComponents(fromKey: "\(key)[]", value: value)
}
} else if let value = value as? NSNumber {
if value.isBool {
components.append((escape(key), escape((value.boolValue ? "1" : "0"))))
} else {
components.append((escape(key), escape("\(value)")))
}
} else if let bool = value as? Bool {
components.append((escape(key), escape((bool ? "1" : "0"))))
} else {
components.append((escape(key), escape("\(value)")))
}
return components
}
public func escape(_ string: String) -> String {
let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
let subDelimitersToEncode = "!$&'()*+,;="
var allowedCharacterSet = CharacterSet.urlQueryAllowed
allowedCharacterSet.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")
var escaped = ""
if #available(iOS 8.3, *) {
escaped = string.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? string
} else {
let batchSize = 50
var index = string.startIndex
while index != string.endIndex {
let startIndex = index
let endIndex = string.index(index, offsetBy: batchSize, limitedBy: string.endIndex) ?? string.endIndex
let range = startIndex..<endIndex
let substring = string.substring(with: range)
escaped += substring.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? substring
index = endIndex
}
}
return escaped
}
그리고 한 가지 확장:
extension NSNumber {
fileprivate var isBool: Bool { return CFBooleanGetTypeID() == CFGetTypeID(self) }}
이건 일시적이야 더 나은 해결책이 될 거야
도움이 됐으면 좋겠는데...
스위프트 4.2
func percentEscapeString(_ string: String) -> String {
var characterSet = CharacterSet.alphanumerics
characterSet.insert(charactersIn: "-._* ")
return string
.addingPercentEncoding(withAllowedCharacters: characterSet)!
.replacingOccurrences(of: " ", with: " ")
.replacingOccurrences(of: " ", with: " ", options: [], range: nil)
.replacingOccurrences(of: "\"", with: "", options: NSString.CompareOptions.literal, range:nil)
}
// Set encoded values to Dict values you can decode keys if required
dictData.forEach { (key, value) in
if let val = value as? String {
dictData[key] = self.percentEscapeString(val)
} else {
dictData[key] = value
}
}
이것은 나에게 효과가 있었고, 이것은 소스 https://gist.github.com/HomerJSimpson/80c95f0424b8e9718a40의 링크입니다.
이 코드를 swift로 변환할 수 있습니까? 이미 시도했지만 처리할 수 없었습니다.이 코드 블록이 도움이 될지도 몰라감사해요.
let myParams:NSString = "username=user1&password=12345"
let myParamsNSData:NSData = NSData(base64EncodedString: myParams, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)!
let myParamsLength:NSString = NSString(UTF8String: myParamsNSData.length)
let myRequest: NSMutableURLRequest = NSURL(fileURLWithPath: self.url)
myRequest.HTTPMethod = "POST"
myRequest.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
myRequest.HTTPBody = myParamsNSData
var data2: NSData!
var error2: NSError!
사전 매개 변수를 문자열로 구문 분석:
-(NSData *)encodeParameters:(NSDictionary *)parameters {
NSMutableArray *list = [NSMutableArray new];
for (NSString *key in [parameters allKeys]) {
id obj = [parameters objectForKey:key];
NSString *path = [NSString stringWithFormat:@"%@=%@", key, obj];
[list addObject:path];
}
return [[list componentsJoinedByString:@"&"] dataUsingEncoding:NSUTF8StringEncoding];
}
사용방법:
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:[self encodeParameters:parameters]];
Swift 5에서 다음 코드가 오늘 작동하도록 테스트되었습니다.
let url = URL(string: "https://something")
var request = URLRequest(url: url!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let post = "parameter1=abc¶meter2=abc"
let postData = post.data(using: String.Encoding.ascii, allowLossyConversion: true)!
request.httpBody = postData
let params:[String: Any]
if "application/x-www-form-urlencoded" {
let bodyData = params.stringFromHttpParameters()
self.request.httpBody = bodyData.data(using: String.Encoding.utf8)}
if "application/json"{
do {
self.request.httpBody = try JSONSerialization.data(withJSONObject: params, options: JSONSerialization.WritingOptions())
} catch {
print("bad things happened")
}
}
확장 사전
func stringFromHttpParameters() -> String {
let parameterArray = self.map { (key, value) -> String in let percentEscapedKey = (key as!String).stringByAddingPercentEncodingForURLQueryValue()!
let percentEscapedValue = (value as! String).stringByAddingPercentEncodingForURLQueryValue()!}
return "\(percentEscapedKey)=\(percentEscapedValue)"}
return parameterArray.joined(separator: "&")}
언급URL : https://stackoverflow.com/questions/22063959/post-request-using-application-x-www-form-urlencoded
'programing' 카테고리의 다른 글
페이지 분할 내부: 기능하지 않음 (0) | 2023.03.16 |
---|---|
Oracle에서 CLOB 열을 쿼리하는 방법 (0) | 2023.03.16 |
WordPress 페이지 및 게시물에 PHP 코드 삽입 (0) | 2023.03.16 |
동적 키를 사용하여 개체의 인터페이스를 정의하려면 어떻게 해야 합니까? (0) | 2023.03.16 |
AngularJs ng클릭으로 다른 페이지로 이동(Ionic 프레임워크 사용) (0) | 2023.03.16 |