Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 为什么URLSession会超时或失败,并出现缺少参数的错误?_Swift_Django_Django Rest Framework_Django Socialauth_Urlsession - Fatal编程技术网

Swift 为什么URLSession会超时或失败,并出现缺少参数的错误?

Swift 为什么URLSession会超时或失败,并出现缺少参数的错误?,swift,django,django-rest-framework,django-socialauth,urlsession,Swift,Django,Django Rest Framework,Django Socialauth,Urlsession,我不明白为什么这个URLSession调用超时 let jsonUrlString = "https://myapp.herokuapp.com/api-auth/invalidate-sessions/" guard let url = URL(string: jsonUrlString) else { return } var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("Bearer

我不明白为什么这个URLSession调用超时

let jsonUrlString = "https://myapp.herokuapp.com/api-auth/invalidate-sessions/"
guard let url = URL(string: jsonUrlString) else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Bearer " + accessToken!, forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let params = ["client_id": djangoAppClientID,]
guard let httpBody = try? JSONSerialization.data(withJSONObject: params, options: []) else { return }
request.httpBody = httpBody

URLSession.shared.dataTask(with: request) { (data, response, err) in
    if let httpResponse = response as? HTTPURLResponse {
        if httpResponse.statusCode == 204 {
            print("Success!")
        } else {
            print("Failure, error = ", err as Any)
        }
    }
}.resume()
服务器立即完成失效会话。这是rest_framework_social_oauth2中的一个方法,我已经用print语句对它进行了检测,以查看它是否达到了我的预期,并返回204状态代码:

2018-07-06T03:52:27.651829+00:00 app[web.1]: 10.11.239.176 - - [05/Jul/2018:20:52:27 -0700] "POST /api-auth/invalidate-sessions/ HTTP/1.1" 204 2 "-“ "myapp/1 CFNetwork/897.15 Darwin/17.6.0"
是的,在客户端(上面的代码),它会挂起60秒,然后打印:

Failure, error = Optional(Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSUnderlyingError=0x60800005a670 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x60000009fb80 [0x106f80c80]>{length = 16, capacity = 16, bytes = 0x100201bb22caef6d0000000000000000}, _kCFStreamErrorCodeKey=57, _kCFStreamErrorDomainKey=1}}, NSErrorFailingURLStringKey=https://myapp.herokuapp.com/api-auth/invalidate-sessions/, NSErrorFailingURLKey=https://myapp.herokuapp.com/api-auth/invalidate-sessions/, _kCFStreamErrorDomainKey=1, _kCFStreamErrorCodeKey=57, NSLocalizedDescription=The network connection was lost.})

可能的复制品我研究了一会儿,排除了这种可能性。结果证明这与我的URLSession请求有关。请参阅上面的更新。您的curl请求将
客户端id作为
应用程序/x-www-form-urlencoded
发送,而不是
应用程序/json
。您的邮递员图像不太清楚您是如何设置请求的,尤其是您正在隐藏请求正文。但是,由于您在URL参数中包含了
client\u id
,它可能会发送一些与Swift代码或curl命令不同的请求。您确定您的服务器接受json吗?(我的意思是,不是响应格式,而是请求内容。)@OOPer,我已经更新了我的帖子,以显示body选项卡中显示的内容。我尝试过Postman和URLsession的各种方法,包括在标题中显式地为“Content Type”设置“application/x-www-form-urlencoded”。但我承认我在抓救命稻草。。。我还用服务器端代码更新了我的帖子,以显示成功后返回的内容(即挂起期间服务器端发生的情况)。对不起,我不擅长Django,我不能说您的服务器代码是否可以接受
application/json
。但是我可以说你的成功案例(curl)和半成功案例(postman)都是在
application/x-www-form-urlencoded
中发送请求的。您明确地说为“内容类型”设置“application/x-www-form-urlencoded”,但是您是否正确地设置了请求主体?不能对
应用程序/x-www-form-urlencoded
使用
JSONSerialization
curl -H "Authorization: Bearer <my access token>" -X POST -d "client_id=<my client id>" https://myapp.herokuapp.com/api-auth/invalidate-sessions/
Moe:Server dylan$ curl -v -H "Authorization: Bearer yyyyyyyyyyyyyyy" -X POST -d "client_id=xxxxxxxxxxxxxxxxxxxxxxxxx" https://myapp.herokuapp.com/api-auth/invalidate-sessions/
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 52.20.65.241...
* TCP_NODELAY set
* Connected to myapp.herokuapp.com (52.20.65.241) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: C=US; ST=California; L=San Francisco; O=Heroku, Inc.; CN=*.herokuapp.com
*  start date: Apr 19 00:00:00 2017 GMT
*  expire date: Jun 22 12:00:00 2020 GMT
*  subjectAltName: host "myapp.herokuapp.com" matched cert's "*.herokuapp.com"
*  issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert SHA2 High Assurance Server CA
*  SSL certificate verify ok.
 > POST /api-auth/invalidate-sessions/ HTTP/1.1
 > Host: myapp.herokuapp.com
 > User-Agent: curl/7.54.0
 > Accept: */*
 > Authorization: Bearer yyyyyyyyyyyyyyy
 > Content-Length: 50
 > Content-Type: application/x-www-form-urlencoded
 > 
* upload completely sent off: 50 out of 50 bytes
 < HTTP/1.1 204 No Content
 < Connection: keep-alive
 < Server: gunicorn/19.8.1
 < Date: Sat, 07 Jul 2018 02:44:30 GMT
 < Content-Type: application/json
 < Vary: Accept
 < Allow: OPTIONS, POST
 < X-Frame-Options: SAMEORIGIN
 < Content-Length: 2
 < Via: 1.1 vegur
 < 
* Connection #0 to host myapp.herokuapp.com left intact
@api_view(['POST'])
@authentication_classes([OAuth2Authentication])
@permission_classes([permissions.IsAuthenticated])
def invalidate_sessions(request):
    client_id = request.data.get("client_id", None)
    if client_id is None:
        return Response({
            "client_id": ["This field is required."]
        }, status=status.HTTP_400_BAD_REQUEST)

    try:
        app = Application.objects.get(client_id=client_id)
    except Application.DoesNotExist:
        return Response({
        "detail": "The application linked to the provided client_id could not be found."
        }, status=status.HTTP_400_BAD_REQUEST)

    tokens = AccessToken.objects.filter(user=request.user, application=app)
    tokens.delete()
    return Response({}, status=status.HTTP_204_NO_CONTENT)