Swift URLSessionDataTask忽略URLRequest';s httpMethod属性

Swift URLSessionDataTask忽略URLRequest';s httpMethod属性,swift,http,nsurlsession,nsurlrequest,nsurlsessiondatatask,Swift,Http,Nsurlsession,Nsurlrequest,Nsurlsessiondatatask,我遇到了一个奇怪的问题,我无法对一个基于GraphQL的REST服务进行简单的POST请求 问题是,无论我在URLRequest类的httpMethod属性中设置了什么,它总是使用GET 我做了一些测试来排除一些问题。例如,我在请求中设置了一个头,我可以验证该头是否被发送到服务器(通过Charles Proxy验证) 这是您可以粘贴并在操场上运行的代码: import PlaygroundSupport import Foundation PlaygroundPage.current.needs

我遇到了一个奇怪的问题,我无法对一个基于GraphQL的REST服务进行简单的POST请求

问题是,无论我在
URLRequest
类的
httpMethod
属性中设置了什么,它总是使用
GET

我做了一些测试来排除一些问题。例如,我在请求中设置了一个头,我可以验证该头是否被发送到服务器(通过Charles Proxy验证)

这是您可以粘贴并在操场上运行的代码:

import PlaygroundSupport
import Foundation
PlaygroundPage.current.needsIndefiniteExecution = true

let url = URL(string: "http://graphql.anilist.co/")!
let internalSession = URLSession(configuration: .default)
var request = URLRequest(url: url)
request.httpMethod = "POST"
let headers = ["content-type": "application/json"]
request.allHTTPHeaderFields = headers
request.httpBody =
"""
{"query":"query (\n\t$season: MediaSeason,\n\t$year: Int,\n\t$format: MediaFormat,\n\t$excludeFormat: MediaFormat,\n\t$status: MediaStatus,\n\t$minEpisodes: Int,\n\t$page: Int,\n){\n\tPage(page: $page) {\n\t\tpageInfo {\n\t\t\thasNextPage\n\t\t\ttotal\n\t\t}\n\t\tmedia(\n\t\t\tseason: $season\n\t\t\tseasonYear: $year\n\t\t\tformat: $format,\n\t\t\tformat_not: $excludeFormat,\n\t\t\tstatus: $status,\n\t\t\tepisodes_greater: $minEpisodes,\n\t\t\tisAdult: false,\n\t\t\ttype: ANIME,\n\t\t\tsort: TITLE_ROMAJI,\n\t\t) {\n\t\t\t\nid\nidMal\ntitle {\n\tromaji\n\tnative\n\tenglish\n}\nstartDate {\n\tyear\n\tmonth\n\tday\n}\nendDate {\n\tyear\n\tmonth\n\tday\n}\nstatus\nseason\nformat\ngenres\nsynonyms\nduration\npopularity\nepisodes\nsource(version: 2)\ncountryOfOrigin\nhashtag\naverageScore\nsiteUrl\ndescription\nbannerImage\ncoverImage {\n\textraLarge\n\tcolor\n}\ntrailer {\n\tid\n\tsite\n\tthumbnail\n}\nexternalLinks {\n\tsite\n\turl\n}\nrankings {\n\trank\n\ttype\n\tseason\n\tallTime\n}\nstudios(isMain: true) {\n\tnodes {\n\t\tid\n\t\tname\n\t\tsiteUrl\n\t}\n}\nrelations {\n\tedges {\n\t\trelationType(version: 2)\n\t\tnode {\n\t\t\tid\n\t\t\ttitle {\n\t\t\t\tromaji\n\t\t\t\tnative\n\t\t\t\tenglish\n\t\t\t}\n\t\t\tsiteUrl\n\t\t}\n\t}\n}\n\nairingSchedule(\n\tnotYetAired: true\n\tperPage: 2\n) {\n\tnodes {\n\t\tepisode\n\t\tairingAt\n\t}\n}\n\n\t\t}\n\t}\n}","variables":{"season": WINTER,"year": 2019,"page": 1, "perPage": 100}}
""".data(using: .utf8)
print("THE REQUEST \(String(describing: request.httpMethod))")
let task = internalSession.dataTask(with: request, completionHandler: { (data, response, error) in
    if let e = error {
        print("ERROR: \(e)")
    } else if let response = response as? HTTPURLResponse {
        print("THE RESPONSE: \(response)")
        let json = try! JSONSerialization.jsonObject(with: data!, options: [])
        print(json)
    }
})
task.resume()

(请忽略所有强制展开选项并强制
尝试!
,这是测试代码)

预期结果

我希望web服务返回类似以下内容的JSON(简化):

服务抱怨请求是GET请求,应该是POST,我明确地告诉URLRequest使用POST。如果查看Charles或其他代理中的请求,您确实会看到该请求是作为GET请求完成的,并且
httpBody
属性被丢弃。如果编辑标题并添加另一个标题,如下所示:

let headers = ["content-type": "application/json", "foo": "bar"]
您将在代理中看到头被正确发送

我能得出的唯一结论是,
URLSessionDataTask
存在一个内部问题,它强制只执行GET请求。我尝试将其更改为下载任务,但同样的问题也发生了。所以我的代码一定有问题,但我找不到

编辑:

根据请求,这是邮递员使用的请求。我已将请求导出到CURL,以使其易于导入

curl -X POST \
  https://graphql.anilist.co/ \
  -H 'Content-Type: application/json' \
  -H 'Postman-Token: 49d7e55e-35c2-4a3c-82f0-4eccb1250fc0' \
  -H 'cache-control: no-cache' \
  -d '{"query":"query (\n\t$season: MediaSeason,\n\t$year: Int,\n\t$format: MediaFormat,\n\t$excludeFormat: MediaFormat,\n\t$status: MediaStatus,\n\t$minEpisodes: Int,\n\t$page: Int,\n){\n\tPage(page: $page) {\n\t\tpageInfo {\n\t\t\thasNextPage\n\t\t\ttotal\n\t\t}\n\t\tmedia(\n\t\t\tseason: $season\n\t\t\tseasonYear: $year\n\t\t\tformat: $format,\n\t\t\tformat_not: $excludeFormat,\n\t\t\tstatus: $status,\n\t\t\tepisodes_greater: $minEpisodes,\n\t\t\tisAdult: false,\n\t\t\ttype: ANIME,\n\t\t\tsort: TITLE_ROMAJI,\n\t\t) {\n\t\t\t\nid\nidMal\ntitle {\n\tromaji\n\tnative\n\tenglish\n}\nstartDate {\n\tyear\n\tmonth\n\tday\n}\nendDate {\n\tyear\n\tmonth\n\tday\n}\nstatus\nseason\nformat\ngenres\nsynonyms\nduration\npopularity\nepisodes\nsource(version: 2)\ncountryOfOrigin\nhashtag\naverageScore\nsiteUrl\ndescription\nbannerImage\ncoverImage {\n\textraLarge\n\tcolor\n}\ntrailer {\n\tid\n\tsite\n\tthumbnail\n}\nexternalLinks {\n\tsite\n\turl\n}\nrankings {\n\trank\n\ttype\n\tseason\n\tallTime\n}\nstudios(isMain: true) {\n\tnodes {\n\t\tid\n\t\tname\n\t\tsiteUrl\n\t}\n}\nrelations {\n\tedges {\n\t\trelationType(version: 2)\n\t\tnode {\n\t\t\tid\n\t\t\ttitle {\n\t\t\t\tromaji\n\t\t\t\tnative\n\t\t\t\tenglish\n\t\t\t}\n\t\t\tsiteUrl\n\t\t}\n\t}\n}\n\nairingSchedule(\n\tnotYetAired: true\n\tperPage: 2\n) {\n\tnodes {\n\t\tepisode\n\t\tairingAt\n\t}\n}\n\n\t\t}\n\t}\n}","variables":{"year":2019,"season":"WINTER","page":1, "limit": 12}}'

我在这里看到的唯一区别是,在你的操场上的http://和在你的邮递员上的http://


因此,只要在您的
游乐场将
http://
替换为
https://

您与邮递员核实过这项服务了吗?@DharmeshKheni是的。它很好用。你能在你的问题中加入你对邮递员的尝试吗?对不起,你是什么意思?你想让我添加邮递员请求吗?是的。。。。。。。。。。。。。。
let headers = ["content-type": "application/json", "foo": "bar"]
curl -X POST \
  https://graphql.anilist.co/ \
  -H 'Content-Type: application/json' \
  -H 'Postman-Token: 49d7e55e-35c2-4a3c-82f0-4eccb1250fc0' \
  -H 'cache-control: no-cache' \
  -d '{"query":"query (\n\t$season: MediaSeason,\n\t$year: Int,\n\t$format: MediaFormat,\n\t$excludeFormat: MediaFormat,\n\t$status: MediaStatus,\n\t$minEpisodes: Int,\n\t$page: Int,\n){\n\tPage(page: $page) {\n\t\tpageInfo {\n\t\t\thasNextPage\n\t\t\ttotal\n\t\t}\n\t\tmedia(\n\t\t\tseason: $season\n\t\t\tseasonYear: $year\n\t\t\tformat: $format,\n\t\t\tformat_not: $excludeFormat,\n\t\t\tstatus: $status,\n\t\t\tepisodes_greater: $minEpisodes,\n\t\t\tisAdult: false,\n\t\t\ttype: ANIME,\n\t\t\tsort: TITLE_ROMAJI,\n\t\t) {\n\t\t\t\nid\nidMal\ntitle {\n\tromaji\n\tnative\n\tenglish\n}\nstartDate {\n\tyear\n\tmonth\n\tday\n}\nendDate {\n\tyear\n\tmonth\n\tday\n}\nstatus\nseason\nformat\ngenres\nsynonyms\nduration\npopularity\nepisodes\nsource(version: 2)\ncountryOfOrigin\nhashtag\naverageScore\nsiteUrl\ndescription\nbannerImage\ncoverImage {\n\textraLarge\n\tcolor\n}\ntrailer {\n\tid\n\tsite\n\tthumbnail\n}\nexternalLinks {\n\tsite\n\turl\n}\nrankings {\n\trank\n\ttype\n\tseason\n\tallTime\n}\nstudios(isMain: true) {\n\tnodes {\n\t\tid\n\t\tname\n\t\tsiteUrl\n\t}\n}\nrelations {\n\tedges {\n\t\trelationType(version: 2)\n\t\tnode {\n\t\t\tid\n\t\t\ttitle {\n\t\t\t\tromaji\n\t\t\t\tnative\n\t\t\t\tenglish\n\t\t\t}\n\t\t\tsiteUrl\n\t\t}\n\t}\n}\n\nairingSchedule(\n\tnotYetAired: true\n\tperPage: 2\n) {\n\tnodes {\n\t\tepisode\n\t\tairingAt\n\t}\n}\n\n\t\t}\n\t}\n}","variables":{"year":2019,"season":"WINTER","page":1, "limit": 12}}'