HTTP DELETE 在浏览器中有效,但在 Postman 或 IOS 应用程序中无效
HTTP DELETE Works From Browser But Not From Postman or IOS App
尝试向我的休息 api 发出 http 请求时,我在使用以下代码时不断收到 401 错误。我在发出任何其他类型的请求时都没有收到此错误。我在下面提供了发出请求的函数。
func deleteEvent(id: Int){
eventUrl.append(String(id))
let request = NSMutableURLRequest(url: NSURL(string: eventUrl)! as URL)
request.httpMethod = "DELETE"
print(eventUrl)
eventUrl.removeLast()
print(self.token!)
request.allHTTPHeaderFields = ["Authorization": "Token \(self.token)"]
let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
if error != nil {
print("error=\(String(describing: error))")
//put variable that triggers error try again view here
return
}
print("response = \(String(describing: response))")
}
task.resume()
}
用postman发送删除请求时,剩下的api只是returns我想删除但没有删除的数据。 作为参考,我已经发布了与此请求相关的视图和权限 类 非常感谢任何帮助理解这可能导致错误的原因!
Views.py
class UserProfileFeedViewSet(viewsets.ModelViewSet):
"""Handles creating, reading and updating profile feed items"""
authentication_classes = (TokenAuthentication,)
serializer_class = serializers.ProfileFeedItemSerializer
queryset = models.ProfileFeedItem.objects.all()
permission_classes = (permissions.UpdateOwnStatus, IsAuthenticated)
def perform_create(self, serializer):
"""Sets the user profile to the logged in user"""
#
serializer.save(user_profile=self.request.user)
Permissions.py
class UpdateOwnStatus(permissions.BasePermission):
"""Allow users to update their own status"""
def has_object_permission(self, request, view, obj):
"""Check the user is trying to update their own status"""
if request.method in permissions.SAFE_METHODS:
return True
return obj.user_profile.id == request.user.id
HEADER 通过邮递员发送删除请求
前言:您从问题中遗漏了太多相关信息,无法正确回答。您的 Swift 代码看起来有点像初学者,或者好像是在没有太多经验的情况下从 Objective-C 迁移过来的,请不要生气。
我不知道为什么 POSTMAN 会失败,但我在 Swift 代码中看到了一些危险信号,您可能想查看一下以找出 iOS 应用程序失败的原因。
我首先注意到 eventUrl
似乎是包含 deleteEvent
函数的类型的 String
属性。你通过附加事件 id
来改变它,从中构造一个 URL (奇怪的是,见下文),然后再次改变它。虽然这本身不一定是错误的,但它可能会打开赛车条件的大门,具体取决于您的应用程序的整体工作方式。
更重要的是:您的 eventUrl
是否以“/”结尾?我假设您的 DELETE 端点是 https://somedomain.com/some/path/<id>
的形式,对吗?现在如果 eventUrl
只包含 https://somedomain.com/some/path
你的代码构造 https://somedomain.com/some/path<id>
。缺少最后一个破折号,这肯定会使您的后端关闭(我不能这么说,因为这取决于路径在您的服务器应用程序中的解析方式)。
很难说 iOS 应用程序还有什么其他功能,但除了这个潜在的陷阱之外,我真的建议尽可能使用正确的 Swift 类型。这是您的方法的清理版本,希望在调试时对您有所帮助:
func deleteEvent(id: Int) {
guard let baseUrl = URL(string: eventUrl), let token = token else {
// add more error handling code here and/or put a breakpoint here to inspect
print("Could not create proper eventUrl or token is nil!")
return
}
let deletionUrl = baseUrl.appendingPathComponent("\(id)")
print("Deletion URL with appended id: \(deletionUrl.absoluteString)")
var request = URLRequest(url: deletionUrl)
request.httpMethod = "DELETE"
print(token) // ensure this is correct
request.allHTTPHeaderFields = ["Authorization": "Token \(token)"]
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Encountered network error: \(error)")
return
}
if let httpResponse = response as? HTTPURLResponse {
// this is basically also debugging code
print("Endpoint responded with status: \(httpResponse.statusCode)")
print(" with headers:\n\(httpResponse.allHeaderFields)")
}
// Debug output of the data:
if let data = data {
let payloadAsSimpleString = String(data: data, encoding: .utf8) ?? "(can't parse payload)"
print("Response contains payload\n\(payloadAsSimpleString)")
}
}
task.resume()
}
这显然在错误处理等方面仍然受到限制,但速度更快一些并且包含更多希望对您有所帮助的控制台输出。
最后一件重要的事情是,您必须确保 iOS 不会因为 Apple Transport Security: Make sure your plist has the expected entries if needed (see also 而简单地阻止您的请求以进行快速介绍)。
尝试向我的休息 api 发出 http 请求时,我在使用以下代码时不断收到 401 错误。我在发出任何其他类型的请求时都没有收到此错误。我在下面提供了发出请求的函数。
func deleteEvent(id: Int){
eventUrl.append(String(id))
let request = NSMutableURLRequest(url: NSURL(string: eventUrl)! as URL)
request.httpMethod = "DELETE"
print(eventUrl)
eventUrl.removeLast()
print(self.token!)
request.allHTTPHeaderFields = ["Authorization": "Token \(self.token)"]
let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
if error != nil {
print("error=\(String(describing: error))")
//put variable that triggers error try again view here
return
}
print("response = \(String(describing: response))")
}
task.resume()
}
用postman发送删除请求时,剩下的api只是returns我想删除但没有删除的数据。 作为参考,我已经发布了与此请求相关的视图和权限 类 非常感谢任何帮助理解这可能导致错误的原因!
Views.py
class UserProfileFeedViewSet(viewsets.ModelViewSet):
"""Handles creating, reading and updating profile feed items"""
authentication_classes = (TokenAuthentication,)
serializer_class = serializers.ProfileFeedItemSerializer
queryset = models.ProfileFeedItem.objects.all()
permission_classes = (permissions.UpdateOwnStatus, IsAuthenticated)
def perform_create(self, serializer):
"""Sets the user profile to the logged in user"""
#
serializer.save(user_profile=self.request.user)
Permissions.py
class UpdateOwnStatus(permissions.BasePermission):
"""Allow users to update their own status"""
def has_object_permission(self, request, view, obj):
"""Check the user is trying to update their own status"""
if request.method in permissions.SAFE_METHODS:
return True
return obj.user_profile.id == request.user.id
HEADER 通过邮递员发送删除请求
前言:您从问题中遗漏了太多相关信息,无法正确回答。您的 Swift 代码看起来有点像初学者,或者好像是在没有太多经验的情况下从 Objective-C 迁移过来的,请不要生气。
我不知道为什么 POSTMAN 会失败,但我在 Swift 代码中看到了一些危险信号,您可能想查看一下以找出 iOS 应用程序失败的原因。
我首先注意到 eventUrl
似乎是包含 deleteEvent
函数的类型的 String
属性。你通过附加事件 id
来改变它,从中构造一个 URL (奇怪的是,见下文),然后再次改变它。虽然这本身不一定是错误的,但它可能会打开赛车条件的大门,具体取决于您的应用程序的整体工作方式。
更重要的是:您的 eventUrl
是否以“/”结尾?我假设您的 DELETE 端点是 https://somedomain.com/some/path/<id>
的形式,对吗?现在如果 eventUrl
只包含 https://somedomain.com/some/path
你的代码构造 https://somedomain.com/some/path<id>
。缺少最后一个破折号,这肯定会使您的后端关闭(我不能这么说,因为这取决于路径在您的服务器应用程序中的解析方式)。
很难说 iOS 应用程序还有什么其他功能,但除了这个潜在的陷阱之外,我真的建议尽可能使用正确的 Swift 类型。这是您的方法的清理版本,希望在调试时对您有所帮助:
func deleteEvent(id: Int) {
guard let baseUrl = URL(string: eventUrl), let token = token else {
// add more error handling code here and/or put a breakpoint here to inspect
print("Could not create proper eventUrl or token is nil!")
return
}
let deletionUrl = baseUrl.appendingPathComponent("\(id)")
print("Deletion URL with appended id: \(deletionUrl.absoluteString)")
var request = URLRequest(url: deletionUrl)
request.httpMethod = "DELETE"
print(token) // ensure this is correct
request.allHTTPHeaderFields = ["Authorization": "Token \(token)"]
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Encountered network error: \(error)")
return
}
if let httpResponse = response as? HTTPURLResponse {
// this is basically also debugging code
print("Endpoint responded with status: \(httpResponse.statusCode)")
print(" with headers:\n\(httpResponse.allHeaderFields)")
}
// Debug output of the data:
if let data = data {
let payloadAsSimpleString = String(data: data, encoding: .utf8) ?? "(can't parse payload)"
print("Response contains payload\n\(payloadAsSimpleString)")
}
}
task.resume()
}
这显然在错误处理等方面仍然受到限制,但速度更快一些并且包含更多希望对您有所帮助的控制台输出。
最后一件重要的事情是,您必须确保 iOS 不会因为 Apple Transport Security: Make sure your plist has the expected entries if needed (see also