ExtJS 5 应用程序 + Django rest 框架 CORS 错误时更改存储的 URL



我正在开发一个使用 Django-rest-framework 服务的 ExtJS 应用程序。我正在使用 CORS 标头来允许从服务(https://github.com/OttoYiu/django-cors-headers(获取数据。

发生的情况是,在某个时间点,我想更改商店中的URL。当我这样做时,我收到以下错误:

XMLHttpRequest cannot load http://10.98.0.241:8000/reacsearch/as?_dc=1418831884352&page=1&start=0&limit=25. The request was redirected to 'http://10.98.0.241:8000/reacsearch/as/?_dc=1418831884352&page=1&start=0&limit=25', which is disallowed for cross-origin requests that require preflight.

在settings.oy中,我为CORS定义了以下属性

CORS_ALLOW_METHODS = (
        'GET',
        'OPTIONS'
    )
CORS_ORIGIN_ALLOW_ALL = True

当我使用 URL 列出数据库中的所有元素时,这工作正常,但是当我更改另一个 URL 的存储时,我收到上述错误。此外,该链接在浏览器中工作正常。

商店 URL 更改的方式如下:

var store = Ext.getStore(storeName);
store.getProxy().setUrl(newURL);
store.load();

视图之间的区别在于,在应用程序上运行的两个视图集是视图集,而另一个只是泛型列表

class Example1viewset(viewsets.ModelViewSet):
    """
    API endpoing that allows metabolites to be viewed.
    """
    queryset = examples1.objects.all()
    serializer_class = Example1Serializer
class Example1SearchList(generics.ListAPIView):
    serializer_class = Example1Serializer
    def get_queryset(self):
        queryset = Example.objects.all()
        if 'attr' in self.kwargs:
            queryset = queryset.filter(Q(attribute1__contains=self.kwargs['attr']) | Q(attribute2__contains=self.kwargs['abbr']))
        return queryset

就像我提到的,这两个示例在浏览器中都可以正常工作(甚至可以通过网络中的其他计算机访问(,但是在应用程序中更改商店的URL时,我收到CORS错误。有谁知道为什么会这样?

谢谢。

编辑:

只是为了澄清,问题不在于更改商店的网址。当我尝试将这些 url 设置为默认值时,但它们在从应用程序访问时不起作用。

我的 urls.py 文件:

router = routers.DefaultRouter()
router.register(r'example', views.Example1ViewSet)
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^reacsearch/(?P<attr>.+)/$', Example1SearchList.as_view()),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))

问题是否与我没有将搜索列表添加到路由器的事实有关?

编辑2

问题解决了,因为我试图从不同的域获取数据。我在 Extjs 中将存储类型更改为 jsonp,并且还允许我的 rest 服务将数据呈现为 jsonp。

提醒一下,如果有人遇到同样的问题,有必要将 ?format=jsonp 添加到商店 url:

http://my/url/?format=jsonp

由于看起来找到了替代解决方案,因此我将解释问题似乎是什么以及为什么替代方案有效。

XMLHttpRequest 无法加载first url 。请求已重定向到"second url",对于需要预检的跨源请求,这是不允许的。

这里的问题是你告诉 Django 强制执行尾部斜杠,这使得它会自动将没有尾部斜杠的 url 重定向到带有尾部斜杠的网址,假设存在一个。这就是为什么,如错误中所述,请求被重定向到第二个 url,您可以知道该 url 缺少尾部斜杠。这是由默认TrueAPPEND_SLASH Django 设置控制的。

问题在于,当 CORS 执行预检请求时(这允许它确定是否可以发出请求(,请求的 URL 上必须有一个有效的响应。由于您正在重定向请求,因此预检请求将失败,并且您无法获得信息。

可以通过在代码中添加尾部斜杠来解决此问题。似乎有一些解决方案可以使用ext执行此操作,但我个人不能推荐特定的解决方案。您还可以手动将 url 设置为使用尾部斜杠,这听起来与您之前所做的一样。

或者你可以使用JSONP...

您已经找到了替代解决方案,即使用 JSONP 发出请求,而不是依赖 CORS。这绕过了预检问题,适用于所有主流浏览器,但有一些缺点需要考虑。您可以通过环顾四周找到有关 CORS 与 JSONP 的更多信息。

如果要推送对 API 的任何更改,则需要 CORS,因为 JSONP 仅支持GET请求。CORS 还具有其他优点,例如中止请求的能力。

最新更新