nginx设置以匹配代理中间件配置

发布于 2025-01-23 06:32:00 字数 15090 浏览 4 评论 0 原文

我有以下setUpproxy.js类,该类将API调用重定向配置为我的服务器。

const { createProxyMiddleware } = require("http-proxy-middleware");

module.exports = function (app) {
    app.use(
        "/api/tours",
        createProxyMiddleware({
            target: "http://localhost:5000", 
            changeOrigin: true,
        })
    );
};

我的app.js看起来

const App = () => {

    const { userDetails } = useContext(AuthContext);
    const { colorMode } = useContext(ColorModeContext);

    let currentTheme = React.useMemo(() =>
        createTheme(deepmerge(getDesignTokens(colorMode)), getThemedComponents(colorMode)),
        [colorMode]
    );
    currentTheme = responsiveFontSizes(currentTheme);
 
    return (
        <ThemeProvider theme={currentTheme}>
            <CssBaseline />
            <Router>
                <Switch>
                    <AuthRoute exact path="/" component={HomePage} />
                    <AuthRoute path="/home" component={HomePage} />
                    <Route path="/public/:id" component={PlayerPage} />
                    <AuthRoute path="/tours/:id" component={PlayerPage} />
                    <Route path="/login">
                        {userDetails == null ? <LoginPage /> : <Redirect to="/home" />}
                    </Route>
                    <Route component={FourOhFour} />
                </Switch>
            </Router>
        </ThemeProvider>
    );
};
export default App;

localhost:3000/tours/eef67wsrr899iop009

这与播放页面看起来像是

const PlayerPage = () => {

    const history = useHistory();

    const { id } = useParams();
    const mode = LocalStorgaeCache.getItem(APP_COLOR_MODE_KEY);
    const theme = createTheme(deepmerge(getDesignTokens(mode), getThemedComponents(mode)));
    
    const { userDetails } = useContext(AuthContext);
    const { tourDetails, isLoading: isLoadingTour, dispatch } = useContext(TourContext);

    const [loading, setLoading] = useState(true);
    const [showTagInfo, setTagId] = useState(0);
    const [tagInfoWindowVisible, showTagInfoWindow] = useState(false);
    const [results] = useState([]);
    const [setTour] = useState();
    const showTagging = useRef(false);
    const [showScan, setShowScan] = useState(false);
    const [addTag, setAddTag] = useState(false);
    const [tagging, setTagging] = useState(false);
    const [myPos, setPos] = useState([]);

    const myLayer = useRef(0);
    const tagEditing = useRef(false);
    const refreshTag = useRef(false);
    const [myTagNumber, setTagNumber] = useState(0);

    const [showPosInfo, setPosInfo] = useState('');
    const [snackMessage, setSnackMessage] = useState('');
    const [isMobile, setIsMobile] = useState(false);

    const [myTags, setTags] = useState([{}]);
    const [watermark, setWatermark] = useState();

    useEffect(() => {
        return () => {
            dispatch(clearLoadedTour());
        };
    }, []);

    useEffect(() => {
        setIsMobile(navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(android)|(webOS)/i));

        const actualLoad = async () => {

            if (userDetails == null) { 
                history.push("/login");
            }
            await getTour(userDetails, id, dispatch);
            setLoading(false);
        };

        if (tourDetails == null) {
            actualLoad();
        }
        else {
            const simulateLoad = async () => {
                await new Promise((r) => setTimeout(r, 1000));
                setLoading(false);
            };
            simulateLoad();
        }
    }, [dispatch, history, id, tourDetails, userDetails]);

    return (
        <ThemeProvider theme={theme}>
            <Fragment>
                <Backdrop
                    sx={{ color: "white", zIndex: (theme) => theme.zIndex.drawer + 1 }}
                    open={loading}>
                    <CircularProgress color="inherit" />
                </Backdrop>
                { tourDetails != null ? (
                <div>
                    {!watermark && <Watermark />}
                    <SimpleSnackBar snackMessage={snackMessage} />
                    <InfoCard
                        tagEditing={tagEditing}
                        setTagging={setTagging}
                        setShow={showTagInfoWindow}
                        refreshTag={refreshTag}
                        setTour={setTour}
                        setShowScan={setShowScan}
                        results={results}
                        tagNumber={myTagNumber}
                        tags={myTags}
                        tour={tourDetails?.MyappTour}
                        pos={myPos}
                        setAddTag={setAddTag}
                        cb={showPosInfo}
                        st={showTagInfo}
                    />
                    {tagInfoWindowVisible && (
                        <MediaCard
                            tagEditing={tagEditing}
                            tagId={showTagInfo}
                            setShow={showTagInfoWindow}
                        />
                    )}
                    <Player
                        token={tourDetails?.azureServiceSasToken}
                        tour={tourDetails?.MyappTour}
                        account={tourDetails?.azureStorageUri}
                        setSnackMessage={setSnackMessage}
                        layer={myLayer}
                        tagging2={tagging}
                        refreshTag={refreshTag}
                        setTagId={setTagId}
                        showTagInfoWindow={showTagInfoWindow}
                        setPosInfo={setPosInfo}
                        setLoading={setLoading}
                        setNewTagPosition={setPos}
                        tagEditing={tagEditing}
                    />
                </div>
                ) : ( <></> ) }
            </Fragment>
        </ThemeProvider>
    );
};
export default PlayerPage;

问题所在,当我用nginx部署该客户端和服务器作为反向效果和负载均衡器时,

myapp.com/tours/eef67wsrr899iop009

不起作用,它仅提供空白页面,而浏览器控制台窗口正在显示

untured syntaxerror:意外的令牌'&lt;' 清单:线:1,列:1,语法错误。

我的清单。json文件是

{
    "short_name": "Myapp",
    "name": "Myapp by vrpm",
    "icons": [
        {
            "src": "favicon.ico",
            "sizes": "64x64 32x32 24x24 16x16",
            "type": "image/x-icon"
        }
    ],
    "start_url": ".",
    "display": "standalone",
    "theme_color": "#000000",
    "background_color": "#ffffff"
}

,我的index.html是

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Myapp</title>
        <meta charset="utf-8" />
        <meta name="theme-color" content="#000000" />
        <meta
            name="viewport"
            content="width=device-width, initial-scale=1, user-scalable=0, maximum-scale=1, minimum-scale=1"
        />
        <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
        <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    </head>
    <body>
        <noscript>You need to enable JavaScript to run this app.</noscript>
        <div id="root"></div>
    </body>
</html>

nginx配置文件,如下所示

worker_processes auto;

events {
  worker_connections 1024;
}

pid /var/run/nginx.pid;

http {

    include mime.types;

    upstream loadbalancer {
        server server:5000 weight=3;
    }

    server {
        listen 80 default_server;
        listen [::]:80 default_server;

        server_name _;

        port_in_redirect off;
        absolute_redirect off;

        return 301 https://$host$request_uri;
    }

    server {
        listen [::]:443 ssl;
        listen 443 ssl;

        server_name myapp.app* myapp.co* myapp-dev.uksouth.azurecontainer.io* localhost*;
        error_page 497 https://$host:$server_port$request_uri;

        error_log /var/log/nginx/client-proxy-error.log;
        access_log /var/log/nginx/client-proxy-access.log;

        ssl_protocols              TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers                ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK;
        ssl_prefer_server_ciphers  on;
        ssl_session_cache          shared:SSL:10m;
        ssl_session_timeout        24h;

        keepalive_timeout 300;
        add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains';

        ssl_certificate     /etc/nginx/certificate.crt;
        ssl_certificate_key /etc/nginx/private.key;

        root /usr/share/nginx/html;
        index index.html index.htm index.nginx-debian.html;

         location / {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
            try_files $uri $uri/ /index.html;
        }

         location /api/auth {
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass http://loadbalancer;
        }
        
        location /api/tours {
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass http://loadbalancer;
        }
    }
}

,此配置可以正常工作,并且没有建议我的清单或我的index.html文件有任何问题。因此,我认为必须是:

如何使用url myApp.com/tours/? /strong>


编辑。请注意,在我的authroute中,我使用以下代码

import { useContext } from "react";
import { AuthContext } from "../context/auth/authContext";
import { Route, Redirect } from "react-router-dom";

const AuthRoute = ({ component: Component, ...rest }) => {
    const authContext = useContext(AuthContext);
    const { isAuthenticated, isAuthorizing } = authContext;
    
    console.log(`Navigation request for ${window.location.href}`);

    return (
        <Route
            {...rest}
            render={props =>
                !isAuthenticated && !isAuthorizing ? (<Redirect to="/login" />) : (<Component {...props} />)
            }
        />
    );
};
export default AuthRoute;

在本地记录请求路径,以打印出请求的路由,并将其导向;所以

https:// localhost的导航请求:3000/tours/3r4et66ksop093jsn

在部署时,从未显示这些消息,这表明NGINX正在介入。


我已经实施了建议的更改,现在我的.config现在看起来像

worker_processes auto;

events {
  worker_connections 1024;
}

pid /var/run/nginx.pid;

http {

    include mime.types;

    upstream loadbalancer {
        server server:5000 weight=3;
    }

    server {
        listen 80 default_server;
        listen [::]:80 default_server;

        server_name _;

        port_in_redirect off;
        absolute_redirect off;

        return 301 https://$host$request_uri;
    }

    server {
        listen [::]:443 ssl;
        listen 443 ssl;

        server_name viewform.app* viewform.co* viewform-dev.uksouth.azurecontainer.io* localhost*;
        error_page 497 https://$host:$server_port$request_uri;

        error_log /var/log/nginx/client-proxy-error.log;
        access_log /var/log/nginx/client-proxy-access.log;

        ssl_protocols              TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers                ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK;
        ssl_prefer_server_ciphers  on;
        ssl_session_cache          shared:SSL:10m;
        ssl_session_timeout        24h;

        keepalive_timeout 300;
        add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains';

        ssl_certificate     /etc/nginx/certificate.crt;
        ssl_certificate_key /etc/nginx/private.key;

        root /usr/share/nginx/html;
        index index.html index.htm index.nginx-debian.html;

        location /api/auth {
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass http://loadbalancer;
        }
        
        location /api/tours {
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass http://loadbalancer;
        }

        location / {
            try_files $uri /index.html;
        }
    }
}

现在,当我导航到dev.myapp/public/tours/我获得了一个空白页,如下所示

untured syntaxerror:意外的令牌'&lt;' subtest.json:1清单:线:1,列:1,语法错误。

我的index.html和subtest.json在上面。

I have the following setupProxy.js class that configures redirection for api calls to my server.

const { createProxyMiddleware } = require("http-proxy-middleware");

module.exports = function (app) {
    app.use(
        "/api/tours",
        createProxyMiddleware({
            target: "http://localhost:5000", 
            changeOrigin: true,
        })
    );
};

My App.js looks like

const App = () => {

    const { userDetails } = useContext(AuthContext);
    const { colorMode } = useContext(ColorModeContext);

    let currentTheme = React.useMemo(() =>
        createTheme(deepmerge(getDesignTokens(colorMode)), getThemedComponents(colorMode)),
        [colorMode]
    );
    currentTheme = responsiveFontSizes(currentTheme);
 
    return (
        <ThemeProvider theme={currentTheme}>
            <CssBaseline />
            <Router>
                <Switch>
                    <AuthRoute exact path="/" component={HomePage} />
                    <AuthRoute path="/home" component={HomePage} />
                    <Route path="/public/:id" component={PlayerPage} />
                    <AuthRoute path="/tours/:id" component={PlayerPage} />
                    <Route path="/login">
                        {userDetails == null ? <LoginPage /> : <Redirect to="/home" />}
                    </Route>
                    <Route component={FourOhFour} />
                </Switch>
            </Router>
        </ThemeProvider>
    );
};
export default App;

and I can navigate to my PlayerPage using a url like

localhost:3000/tours/eef67wsrr899iop009

This loads fine with the PlayerPage looking like

const PlayerPage = () => {

    const history = useHistory();

    const { id } = useParams();
    const mode = LocalStorgaeCache.getItem(APP_COLOR_MODE_KEY);
    const theme = createTheme(deepmerge(getDesignTokens(mode), getThemedComponents(mode)));
    
    const { userDetails } = useContext(AuthContext);
    const { tourDetails, isLoading: isLoadingTour, dispatch } = useContext(TourContext);

    const [loading, setLoading] = useState(true);
    const [showTagInfo, setTagId] = useState(0);
    const [tagInfoWindowVisible, showTagInfoWindow] = useState(false);
    const [results] = useState([]);
    const [setTour] = useState();
    const showTagging = useRef(false);
    const [showScan, setShowScan] = useState(false);
    const [addTag, setAddTag] = useState(false);
    const [tagging, setTagging] = useState(false);
    const [myPos, setPos] = useState([]);

    const myLayer = useRef(0);
    const tagEditing = useRef(false);
    const refreshTag = useRef(false);
    const [myTagNumber, setTagNumber] = useState(0);

    const [showPosInfo, setPosInfo] = useState('');
    const [snackMessage, setSnackMessage] = useState('');
    const [isMobile, setIsMobile] = useState(false);

    const [myTags, setTags] = useState([{}]);
    const [watermark, setWatermark] = useState();

    useEffect(() => {
        return () => {
            dispatch(clearLoadedTour());
        };
    }, []);

    useEffect(() => {
        setIsMobile(navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(android)|(webOS)/i));

        const actualLoad = async () => {

            if (userDetails == null) { 
                history.push("/login");
            }
            await getTour(userDetails, id, dispatch);
            setLoading(false);
        };

        if (tourDetails == null) {
            actualLoad();
        }
        else {
            const simulateLoad = async () => {
                await new Promise((r) => setTimeout(r, 1000));
                setLoading(false);
            };
            simulateLoad();
        }
    }, [dispatch, history, id, tourDetails, userDetails]);

    return (
        <ThemeProvider theme={theme}>
            <Fragment>
                <Backdrop
                    sx={{ color: "white", zIndex: (theme) => theme.zIndex.drawer + 1 }}
                    open={loading}>
                    <CircularProgress color="inherit" />
                </Backdrop>
                { tourDetails != null ? (
                <div>
                    {!watermark && <Watermark />}
                    <SimpleSnackBar snackMessage={snackMessage} />
                    <InfoCard
                        tagEditing={tagEditing}
                        setTagging={setTagging}
                        setShow={showTagInfoWindow}
                        refreshTag={refreshTag}
                        setTour={setTour}
                        setShowScan={setShowScan}
                        results={results}
                        tagNumber={myTagNumber}
                        tags={myTags}
                        tour={tourDetails?.MyappTour}
                        pos={myPos}
                        setAddTag={setAddTag}
                        cb={showPosInfo}
                        st={showTagInfo}
                    />
                    {tagInfoWindowVisible && (
                        <MediaCard
                            tagEditing={tagEditing}
                            tagId={showTagInfo}
                            setShow={showTagInfoWindow}
                        />
                    )}
                    <Player
                        token={tourDetails?.azureServiceSasToken}
                        tour={tourDetails?.MyappTour}
                        account={tourDetails?.azureStorageUri}
                        setSnackMessage={setSnackMessage}
                        layer={myLayer}
                        tagging2={tagging}
                        refreshTag={refreshTag}
                        setTagId={setTagId}
                        showTagInfoWindow={showTagInfoWindow}
                        setPosInfo={setPosInfo}
                        setLoading={setLoading}
                        setNewTagPosition={setPos}
                        tagEditing={tagEditing}
                    />
                </div>
                ) : ( <></> ) }
            </Fragment>
        </ThemeProvider>
    );
};
export default PlayerPage;

The problem is, when I deploy this client and server with NGINX as the reverse-proxy and load balancer, the

myapp.com/tours/eef67wsrr899iop009

does not work, it merely gives a blank page and the browser console window is showing

Uncaught SyntaxError: Unexpected token '<'
Manifest: Line: 1, column: 1, Syntax error.

My manifest.json file is

{
    "short_name": "Myapp",
    "name": "Myapp by vrpm",
    "icons": [
        {
            "src": "favicon.ico",
            "sizes": "64x64 32x32 24x24 16x16",
            "type": "image/x-icon"
        }
    ],
    "start_url": ".",
    "display": "standalone",
    "theme_color": "#000000",
    "background_color": "#ffffff"
}

and my index.html is

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Myapp</title>
        <meta charset="utf-8" />
        <meta name="theme-color" content="#000000" />
        <meta
            name="viewport"
            content="width=device-width, initial-scale=1, user-scalable=0, maximum-scale=1, minimum-scale=1"
        />
        <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
        <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    </head>
    <body>
        <noscript>You need to enable JavaScript to run this app.</noscript>
        <div id="root"></div>
    </body>
</html>

The NGINX configuration file looks as follows

worker_processes auto;

events {
  worker_connections 1024;
}

pid /var/run/nginx.pid;

http {

    include mime.types;

    upstream loadbalancer {
        server server:5000 weight=3;
    }

    server {
        listen 80 default_server;
        listen [::]:80 default_server;

        server_name _;

        port_in_redirect off;
        absolute_redirect off;

        return 301 https://$host$request_uri;
    }

    server {
        listen [::]:443 ssl;
        listen 443 ssl;

        server_name myapp.app* myapp.co* myapp-dev.uksouth.azurecontainer.io* localhost*;
        error_page 497 https://$host:$server_port$request_uri;

        error_log /var/log/nginx/client-proxy-error.log;
        access_log /var/log/nginx/client-proxy-access.log;

        ssl_protocols              TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers                ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK;
        ssl_prefer_server_ciphers  on;
        ssl_session_cache          shared:SSL:10m;
        ssl_session_timeout        24h;

        keepalive_timeout 300;
        add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains';

        ssl_certificate     /etc/nginx/certificate.crt;
        ssl_certificate_key /etc/nginx/private.key;

        root /usr/share/nginx/html;
        index index.html index.htm index.nginx-debian.html;

         location / {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
            try_files $uri $uri/ /index.html;
        }

         location /api/auth {
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass http://loadbalancer;
        }
        
        location /api/tours {
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass http://loadbalancer;
        }
    }
}

Locally, this configuration works fine and there is no suggestion that anything is wrong with my manifest.json or my index.html files. So the question I think must be:

How can I ammend my NGINX proxying to allow for direct routing via the client using the url myapp.com/tours/<some-id>?


Edit. Note, in my AuthRoute, I log the request path using the following code

import { useContext } from "react";
import { AuthContext } from "../context/auth/authContext";
import { Route, Redirect } from "react-router-dom";

const AuthRoute = ({ component: Component, ...rest }) => {
    const authContext = useContext(AuthContext);
    const { isAuthenticated, isAuthorizing } = authContext;
    
    console.log(`Navigation request for ${window.location.href}`);

    return (
        <Route
            {...rest}
            render={props =>
                !isAuthenticated && !isAuthorizing ? (<Redirect to="/login" />) : (<Component {...props} />)
            }
        />
    );
};
export default AuthRoute;

locally this prints out the requested route and it is navgated to; so

Navigation request for https://localhost:3000/tours/3r4et66ksop093jsn

On Azure when deployed, these messages are never displayed which suggests that NGINX is intervieening.


I have implemented the suggested changes and my .config now looks like

worker_processes auto;

events {
  worker_connections 1024;
}

pid /var/run/nginx.pid;

http {

    include mime.types;

    upstream loadbalancer {
        server server:5000 weight=3;
    }

    server {
        listen 80 default_server;
        listen [::]:80 default_server;

        server_name _;

        port_in_redirect off;
        absolute_redirect off;

        return 301 https://$host$request_uri;
    }

    server {
        listen [::]:443 ssl;
        listen 443 ssl;

        server_name viewform.app* viewform.co* viewform-dev.uksouth.azurecontainer.io* localhost*;
        error_page 497 https://$host:$server_port$request_uri;

        error_log /var/log/nginx/client-proxy-error.log;
        access_log /var/log/nginx/client-proxy-access.log;

        ssl_protocols              TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers                ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK;
        ssl_prefer_server_ciphers  on;
        ssl_session_cache          shared:SSL:10m;
        ssl_session_timeout        24h;

        keepalive_timeout 300;
        add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains';

        ssl_certificate     /etc/nginx/certificate.crt;
        ssl_certificate_key /etc/nginx/private.key;

        root /usr/share/nginx/html;
        index index.html index.htm index.nginx-debian.html;

        location /api/auth {
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass http://loadbalancer;
        }
        
        location /api/tours {
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass http://loadbalancer;
        }

        location / {
            try_files $uri /index.html;
        }
    }
}

Now when I navigate to dev.myapp/public/tours/ I get a blank page as shown below

enter image description here

with the following warnings

Uncaught SyntaxError: Unexpected token '<'
manifest.json:1 Manifest: Line: 1, column: 1, Syntax error.

My index.html and manifest.json is above.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

万水千山粽是情ミ 2025-01-30 06:32:00

由于nginx不知道 tours react> react-router 处理的路径,您可以告诉nginx将所有请求重新路由/ root然后,将请求传递到 index.html 的路由,您可以添加正则途径,并将所有请求路由到/ nginx.nginx.conf root位置。由于/根位置正在处理所有其他请求可能不会传递到其他位置,因此最好将当前路线移动到> nginx.conf 中的静态路线下方。

以下是如何将所有请求路由到 index.html 文件
nginx.conf

...
location /api/auth {
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection 'upgrade';
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_pass http://loadbalancer;
}

location /api/tours {
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection 'upgrade';
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_pass http://loadbalancer;
}

location / {
     try_files $uri /index.html; # change as below
}
...

op编辑:在我的软件包中。这就是导致路由失败的原因 - 偷偷摸摸。希望这对别人有帮助。

Since nginx don't know about tours path which is handled by react-router you can either tell nginx to reroute all the request to / root route which then passes the request to index.html or you can add regex path and route all the request to / root location in nginx.conf. Since now / root location is handling all the other request may not get passed to other location so it would be best to move current route below static location in nginx.conf.

Below is how to route all request to index.html file
nginx.conf

...
location /api/auth {
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection 'upgrade';
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_pass http://loadbalancer;
}

location /api/tours {
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection 'upgrade';
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_pass http://loadbalancer;
}

location / {
     try_files $uri /index.html; # change as below
}
...

OP Edit: In my package.json "homepage": ".", needed to be "homepage": "/",. This is what was causing the routing to fail - sneaky. Hopefully this helps someone else.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文