【问题标题】:Why are React URLs conflicting with Django Rest为什么 React URL 与 Django Rest 冲突
【发布时间】:2023-04-06 06:08:01
【问题描述】:

我之前多次使用过这种语法,但现在这给我带来了问题。定义模板 index.html 的 Django url 旨在接收站点的初始请求 (path('')...) 并返回 React 应用程序,然后任何页面 React 请求都将由 React (re_path(...)) 处理。无论如何,问题是如果我删除“re_path 抓取所有”网址。主页会加载,但任何其他页面都不会。现在考虑到过去这并不是什么大问题,我只是添加了正则表达式,它可以工作,即 . re_path(r'^(?:.*)/?$。现在,如果添加此代码,主页不仅不会加载,而且 axios 调用 retrievePicks 甚至不会命中 Django 后端,而是将 index.html 作为原始(大部分不可读)文本返回。但我现在可以转到任何其他页面,它工作正常。我尝试了多种方法,例如使用 fetch 而不是 axios,使用 post/detailed 操作(没有意义,因为它甚至没有进入 django 服务器),添加 Switch 组件,尝试重定向到另一个 url。我不明白为什么所有其他 axios 调用都可以正常工作,而这是唯一一个不能正常工作的。

我的package.json 将代理设置为http://localhost:8000 顺便说一句。

我在一个 linux 服务器上,使用 Gunicorn/Nginx,React 是用 create-react-app 构建的

由 axios 审查的原始文本

<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/lib[...]

App.js

function App() {
  return (
    <Router>
      <Switch>
        <Redirect exact from="/" to="/home" />

      <Route exact path="/login" component={LoginScreen} />
      <Route exact path="/team/:name" component={TeamDetailScreen} />
      <Route exact path="/" component={HomeScreen} />
      </Switch>
    </Router>
  );
}

pickActions

export const retrievePicks = (token) => async (dispatch) => {
    dispatch({type:"PICKS_REQUEST"})
    try{
        const config = {
            headers: {
                "Authorization": `Bearer ${token}`
            }
        }

        const { data } = await axios.get('/api/games/picks/football?week=1', config)
        dispatch({type:"PICKS_SUCCESS", payload:data})
    }catch(err){
        console.log('picks retrieval error', err.response)}

}

urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/games/', include('picksix.urls')),
    path('api/users/', include('user.urls')),
    path('', TemplateView.as_view(template_name="index.html")),
    re_path(r'^(?:.*)/?$',TemplateView.as_view(template_name="index.html"))


]

【问题讨论】:

  • 正则表达式注意:^(?:.*)/?$^.*/?$ 相同,调用(?:...) 本身就很奇怪:如果您了解 RE,您就会知道它的作用以及为什么它可以作为 Django re_path 模式。如果你知道它的作用,你为什么要使用它?因为如果您对此的回答是“因为它有效”,那么对此的回应是“您怎么知道?您所知道的是它还没有损坏尚未,您不知道是否它实际上有效” =)
  • 记住 cmets 是给 cmets 用的,不是用来回答的,记得阅读code of conduct。有人叫你说完全正常的编程结构“奇怪”是你,而不是他们,如果你的帖子解释说你正在使用某些东西,即使你暗示你不明白它为什么起作用,他们绝对应该问你为什么要使用它。

标签: reactjs django-rest-framework axios


【解决方案1】:

所以我能够实施解决方案,尽管我不会称其为完整的“修复”。 我听说在使用来自react-router-dom 的 BrowserRouter 时 url 冲突。所以我硬着头皮使用了HashRouter。出于显而易见的原因,我更喜欢 BrowerRouter,但切换到 HashRouter 允许应用程序按设计工作。即使使用正则表达式路径 re_path(r'^(?:.*)/?$ 它仍然有效,但随后导致 React 在重定向(并简单地定向)时进一步“破坏”url,因此我能够完全删除它,应用程序不仅可以正常工作,但 URL 不能被破坏。我还必须确保 api 调用具有“/”,在 url 之前(我知道这已经是最佳实践,但之前的代码仍然无法使用或不使用它)。我不认为这是一个完整的修复的唯一原因是我仍然希望在 url 中没有散列。

正如我所提到的,我发现有趣的是,除了“/home”React 路由和retrievePicks API 调用之外,所有 url 和 axios 调用(get/post、查询或“静态”)都正常工作.就好像 Django 正在从传入的请求对象解析主机,将其发送到正确的视图并加载反应,并允许请求的 URL 的其余部分通过 React。但是当启动 axios 调用时,它与任何其他页面相比会重复该循环,应用程序能够保持 React url(连同 w/axios 调用)和 Django URL 分开。奇怪的是,当检查服务器的日志时,没有任何异常显示。我可能找错了地方,但这就是我发现的......

_request.META 失败日志

{'wsgi.errors': <gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x7fd92c612580>, 'wsgi.version': (1, 0), 'wsgi.multithread': False,
'wsgi.multiprocess': True, 'wsgi.run_once': False, 'wsgi.file_wrapper': <class 'gunicorn.http.wsgi.FileWrapper'>, 'wsgi.input_terminated': True, 'SERVER_SOFTWARE': 'gunicorn/20.1.0', 'wsgi.input': <gunicorn.http.body.Body object at 0x7fd92c612700>, 'gunicorn.socket': <socket.socket fd=4, family=AddressFamily.AF_UNIX, type=SocketKind.SOCK_STREAM, proto=0, laddr=/tmp/picksixcity.com.socket>, 'REQUEST_METHOD': 'GET', 'QUERY_STRING': '', 'RAW_URI': '/home', 'SERVER_PROTOCOL': 'HTTP/1.0', 'HTTP_HOST': 'localhost', 'HTTP_CONNECTION': 'close', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'HTTP_REFERER': 'http://picksixcity.com/team/DAL', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.9', 'wsgi.url_scheme': 'http', 'REMOTE_ADDR': '', 'SERVER_NAME': 'localhost', 'SERVER_PORT': '80', 'PATH_INFO': '/home', 'SCRIPT_NAME': ''}
/home # this route fails

_request.META 的工作日志

{'wsgi.errors': <gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x7fd92cd21fa0>, 'wsgi.version': (1, 0), 'wsgi.multithread': False, 'wsgi.multiprocess': True, 'wsgi.run_once': False, 'wsgi.file_wrapper': <class 'gunicorn.http.wsgi.FileWrapper'>, 'wsgi.input_terminated': True, 'SERVER_SOFTWARE': 'gunicorn/20.1.0', 'wsgi.input': <gunicorn.http.body.Body object at 0x7fd92ccb3970>, 'gunicorn.socket': <socket.socket fd=4, family=AddressFamily.AF_UNIX, type=SocketKind.SOCK_STREAM, proto=0, laddr=/tmp/picksixcity.com.socket>, 'REQUEST_METHOD': 'GET', 'QUERY_STRING': '', 'RAW_URI': '/team/DAL', 'SERVER_PROTOCOL': 'HTTP/1.0', 'HTTP_HOST':
'localhost', 'HTTP_CONNECTION': 'close', 'HTTP_PRAGMA': 'no-cache', 'HTTP_CACHE_CONTROL': 'no-cache', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.9', 'wsgi.url_scheme': 'http', 'REMOTE_ADDR': '', 'SERVER_NAME': 'localhost', 'SERVER_PORT': '80', 'PATH_INFO': '/team/DAL', 'SCRIPT_NAME': ''}
/team/DAL # this is the route

我同意复制/粘贴一个不理解的代码倾向于“失败时”与“如果失败”的结果,但如果有人经历过这种情况或可以解释为什么会发生这种情况,我会欣赏。我熟悉基本的正则表达式,但在短时间内我不必创建太复杂的模式

【讨论】:

    猜你喜欢
    • 2023-03-12
    • 2022-01-10
    • 2020-07-09
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    • 2016-04-11
    • 2021-03-09
    • 1970-01-01
    相关资源
    最近更新 更多