提问者:小点点

不需要的Apache 302重定向到相同的方法但没有参数


我有一个Django后端平台,其中我使用django-rest框架实现了一个API。

我有一个iOS的应用程序,其中我使用AFNetworking2.0与我的API进行交互,根据情况使用GET和POST。

当我在本地运行整个平台时(使用Django内部运行服务器),一切正常。

当使用Apache运行后端时,会发生一个奇怪的问题。我的iOS应用程序对django-rest框架处理的任何方法发出的第一个请求(无论是GET还是POST)最终会在302重定向到相同的方法,但丢失所有参数。例如,这是我的方法“区域”的Apache日志:

使用GET: 189.122.X.X--[07/May/2014:14:16:50 0200]"GET /recursos/api/districts/?city_id=3HTTP/1.1"302 548 189.122.X--[07/May/2014:14:16:51 0200]"GET /recursos/api/districts/HTTP/1.1"200 399

X. X--[07/May/2014:14:16:15 0200]"POST /recursos/api/districts/HTTP/1.1"302 548 189.122.X--[07/May/2014:14:16:16 0200]"GET /recursos/api/districts/HTTP/1.1"200 399

一些有趣的测试:

  1. 几秒钟后,从iOS应用程序到此API的任何后续GET/POST请求都可以正常工作
  2. 如果我通过浏览器发出请求,无论何时,它都能正常工作:302不会重定向并正确处理请求
  3. 从应用程序内部请求不属于django-rest框架api的方法,正常工作

我不知道还能做些什么来让它在所有这些场景中发挥作用。

为了让它现在工作,我必须打第一个电话,我知道它会失败。等待几秒钟,直到做第二个,这将起作用。因为立即做它会再次失败。

AFNetworkcall看起来像:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    NSString *method = [NSString stringWithFormat:@"%@%@", SERVER_URL, @"ws_districts"];
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
    [dict setValue:@"3" forKey:@"city_id"];
    [manager GET:method
      parameters:dict
         success:^(AFHTTPRequestOperation *operation, id responseObject) {
             NSLog(@"%@ %i",responseObject,city.o_id);
         }
         failure:^(AFHTTPRequestOperation *operation, NSError *error) {
             NSLog(@"%@",error);
         }];

在django-rest框架中,我使用序列化程序:

class DistrictSerializer(serializers.ModelSerializer):
class Meta:
    model = District
    fields = ('id', 'name')

我认为的一种方法:

@csrf_exempt
def districts(request):
if request.method == 'GET':
    city_id = request.GET.get('city_id', None)

    queryset = District.objects.filter(city_id=city_id)

    serializer_context = {'request': request}
    serializer = DistrictSerializer(queryset, context=serializer_context)

    response = JSONResponse(serializer.data)
    return response

elif request.method == 'POST':
    data = JSONParser().parse(request)
    serializer = DistrictSerializer(data=data)
    if serializer.is_valid():
        serializer.save()
        return JSONResponse(serializer.data, status=201)
    return JSONResponse(serializer.errors, status=400)

和网址:

urlpatterns = patterns('views.api',
url(r'^api/districts/$', 'districts'),

有什么暗示吗?


共1个答案

匿名用户

前段时间终于发现了问题:都是和HTTPAccept-Language头有关。

我们的Django应用程序定义了以下语言:

LANGUAGES = (
('en', ugettext('En')),
('pt', ugettext('Pt')),
('es', ugettext('Es')))

在不指定AcceptLanguage标头的情况下发送请求时,它最终会出现在302上。

通过发送带有"en-US, en;q=0.8,pt;q=0.6,es;q=0.4"的请求,它可以正常工作。