django - 更改商店的 URL 时,ExtJS 5 应用程序 + Django rest 框架 CORS 错误

标签 django extjs cors django-rest-framework django-cors-headers

我正在开发一个使用 Django-rest-framework 服务的 ExtJS 应用程序。我正在使用 CORS header 来允许从服务 ( 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 时,我收到上述错误。该链接在浏览器中也能正常工作。

商店网址更改是这样进行的:
var store = Ext.getStore(storeName);
store.getProxy().setUrl(newURL);
store.load();

View 之间的区别在于,在应用程序上工作的两个是 View 集,而另一个只是一个通用列表
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 中将 store 的类型更改为 jsonp,并且我还允许我的 rest 服务将数据呈现为 jsonp。

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

最佳答案

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

XMLHttpRequest cannot load first url. The request was redirected to 'second url', which is disallowed for cross-origin requests that require preflight.



这里的问题是您告诉 Django 强制使用尾部斜杠,这使得它自动将没有尾部斜杠的 url 重定向到带有尾部斜杠的 url,假设存在一个。这就是为什么,如错误中所述,请求被重定向到第二个 url,您可以看出该 url 缺少尾部斜杠。这是由 the APPEND_SLASH Django setting 控制的这是 True默认情况下。

问题是,当 CORS 执行预检请求时,它允许它确定是否可以发出请求,请求的 URL 必须有一个有效的响应。因为您正在重定向请求,所以预检请求失败并且您在没有您的信息的情况下陷入困境。

您可以通过在代码中添加尾部斜杠来解决此问题。似乎有几个solutions for doing this with ext ,但我个人不能推荐特定的。您还可以手动设置 url 以使用尾部斜杠,这听起来就像您之前所做的那样。

或者您可以使用 JSONP...

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

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

关于django - 更改商店的 URL 时,ExtJS 5 应用程序 + Django rest 框架 CORS 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27530027/

相关文章:

python - 如何避免django中的url增加

extjs - 在 Extjs 商店中,我们可以使用 2 列和 2 个值进行查询吗?

javascript - ExtJS 4.0 的颜色字段

node.js - 否 'Access-Control-Allow-Origin' - Node/Apache 端口问题

python - 获取 django 的最新条目

django - 将 robots.txt 添加到我的 Django 应用程序是被 Google 列出的方式吗?

jquery - Ajax POST 和 Django Tastypie

extjs - 获取 Ext JS 版本

rest - 如何在 EmberJS 应用程序中启用 CORS?

javascript - CORS OPTIONS 请求成功,但在 Safari 中挂起