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 而简单地阻止您的请求以进行快速介绍)。