首页 > 解决方案 > HTTP DELETE 在浏览器中有效,但在 Postman 或 IOS 应用中无效

问题描述

尝试向我的 rest 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()

       }

使用邮递员发送删除请求时,其余 api 只返回我要删除的数据,但不删除它。作为参考,我已经发布了与此请求相关的视图和权限类任何帮助理解为什么这可能会导致错误非常感谢!

视图.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)

权限.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

通过邮递员发送带有删除请求的标题 通过邮递员发送带有删除请求的标题

标签: iosswiftdjango-rest-frameworkhttp-headershttprequest

解决方案


前言:您从问题中遗漏了太多相关信息,无法正确回答。您的 Swift 代码看起来有点像初学者,请不要被冒犯,或者好像它是从 Objective-C 迁移而来的,没有太多经验。

我不知道为什么 POSTMAN 会失败,但我在 Swift 代码中看到了一些危险信号,您可能想查看一下以找出您的 iOS 应用程序失败的原因。

我首先注意到这eventUrl似乎是String包含该deleteEvent函数的类型的属性。您通过附加事件来改变它,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而简单地阻止您的请求:如果需要,请确保您的 plist 具有预期的条目(另请参阅此处以获取快速介绍)。


推荐阅读