ExtJS 5应用程序+ Django rest框架更改商店的URL时出现CORS错误 [英] ExtJS 5 application + Django rest framework CORS error when changing URL of store

查看:579
本文介绍了ExtJS 5应用程序+ Django rest框架更改商店的URL时出现CORS错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



会发生什么,在某个时间点我想更改商店的URL。当我这样做,我得到以下错误:

  XMLHttpRequest不能加载http://10.98.0.241:8000/reacsearch/ as?_dc = 1418831884352& page = 1& start = 0& limit = 25。请求已重定向到http://10.98.0.241:8000/reacsearch/as/?_dc=1418831884352&page=1&start=0&limit=25',对于需要预检的跨源请求,不允许该请求。 

在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();

视图之间的区别是,在应用程序上工作的两个是视图,只是一个通用列表

  class Example1viewset(viewsets.ModelViewSet):

API endpoing

queryset = examples1.objects.all()
serializer_class = Example1Serializer

class Example1SearchList(generics.ListAPIView):
serializer_class = Example1Serializer

def get_queryset(self):
queryset = Example.objects.all()

如果'attr'在self.kwargs :
queryset = queryset.filter(Q(attribute1__contains = self.kwargs ['attr'])| Q(attribute2__contains = self.kwargs ['abbr']))

return queryset $像我提到的两个例子在浏览器中工作正常(甚至通过网络中的其他计算机访问),但是,在应用程序中更改商店的URL时,我得到CORS错误。



编辑:

strong>



仅仅为了说明,问题不在于更改商店的网址。由于我尝试将这些网址设置为默认值,但在从应用程序访问时无效。



我的urls.py文件:

  router = routers.DefaultRouter()
router.register(r'example',views.Example1ViewSet)

#使用自动网址路由来上传我们的API。
#此外,我们包括可浏览API的登录URL。
urlpatterns = [
url(r'^',include(router.urls)),
url(r'^ reacsearch /(?P 。+)/ $'示例1SearchList.as_view()),
url(r'^ api-auth /',include('rest_framework.urls',namespace ='rest_framework'))
pre>

是不是这个问题与我不添加搜索列表到路由器的事实有关?



编辑2



问题已解决,因为我尝试从其他域。我在Extjs中将存储类型更改为jsonp,我还允许我的rest服务以jsonp形式呈现数据。



只是提醒,如果有人遇到同样的问题,有必要在商店url中添加?format = jsonp:

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


解决方案

因为它看起来像一个替代解决方案,


XMLHttpRequest无法加载第一个网址。请求被重定向到第二个网址,这对于需要预检的跨源请求是不允许的。


这里的问题是,你告诉Django强制执行尾部斜杠,这使得它自动重定向urls没有尾部斜杠到urls与尾部斜杠,假设一个存在。这就是为什么,如错误所述,请求被重定向到第二个url,你可以告诉它有缺少的尾部斜杠。这由 APPEND_SLASH Django设置,默认为 True



问题是,当CORS执行预检请求,这是允许它确定是否可以做出请求的事件,在请求的URL处必须存在有效​​的响应 。因为您正在重定向请求,所以预检请求失败,您无法获得您的信息。



您可以通过在代码中添加尾部斜杠来解决此问题。似乎有少量解决方案这样做与ext ,但我个人不能推荐一个具体的。



您也可以使用JSONP ...

strong>



您找到了另一种解决方案,即使用JSONP来发出请求,而不是依赖于CORS。这绕过了预检问题,并在所有主流浏览器中工作,但有一些缺点要考虑。您可以通过查找更多有关CORS和JSONP的信息



如果您要对API进行任何更改,那么您将需要CORS,因为JSONP仅支持 GET 请求。还有其他优点,例如中止请求的能力,也是CORS自带的。


I am developing a ExtJS application that uses a Django-rest-framework service. I am using CORS headers to allow fetching the data from the service (https://github.com/OttoYiu/django-cors-headers).

What happens is that at a point in time I want to change the URL from the store. And when I do that I get the following error:

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.

In the settings.oy I define the following properties for the CORS

CORS_ALLOW_METHODS = (
        'GET',
        'OPTIONS'
    )

CORS_ORIGIN_ALLOW_ALL = True

This works fine when I use URLs to list all the elements in my database, however when I change the store for another URL I get the error above. Also the link works fine in the browser.

The store url change is made this way:

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

The difference between the views, is that the two that work on the application are viewsets, while the other is just a generic list

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

Like I mentioned both examples work fine in the browser (even accessing through other computers in the network), however in the application when changing the URL of the store I get the CORS error. Does anyone has any idea why this is happening?

Thank you.

Edit:

Just for clarification, the problem is not in changing the url of the store. As I tried to set those urls as defaults, but they are not working when accessing from the application.

My urls.py file:

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'))

Can it be that the problem is related with the fact that I am not adding the search list to the router?

Edit2

Problem solved since I was trying to fetch data from a different domain. I changed the type of store to jsonp in Extjs, and I also allowed my rest service to render data as jsonp.

Just a reminder if anyone comes accross this same problem, it is necessary to add ?format=jsonp to the store url:

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

解决方案

Since it looks like an alternate solution was found, I'll explain what the issue appeared to be as well as why the alternative works.

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

The issue here is that you are telling Django to enforce the trailing slash, which makes it automatically redirect urls without a trailing slash to urls with a trailing slash, assuming that one exists. This is why, as stated in the error, the request was redirected to the second url, which you can tell has the missing trailing slash. This is controlled by the APPEND_SLASH Django setting which is True by default.

The problem is that when CORS is doing a preflight request, which is what allows it to determine if the request can be made, there must be a valid response at the requested URL. Because you are redirecting the request, the preflight request fails and you're stuck without your information.

You can fix this by adding the trailing slash in your code. There appear to be a few solutions for doing this with ext, but I personally can't recommend a specific one. You can also manually set the url to use the trailing slash, which sounds like what you were doing previously.

Or you can use JSONP...

You've found the alternative solution, which is to use JSONP to make the request instead of relying on CORS. This gets around the preflight issue and works in all major browsers, but there are some drawbacks to consider. You can find more information on CORS vs JSONP by looking around.

You're going to need CORS if you want to push any changes to your API, as JSONP only supports GET requests. There are other advantages, such as the ability to abort requests, that also comes with CORS.

这篇关于ExtJS 5应用程序+ Django rest框架更改商店的URL时出现CORS错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆