【问题标题】:Host NextJs to IIS将 NextJs 托管到 IIS
【发布时间】:2019-03-03 02:36:56
【问题描述】:

美好的一天!

我的同事有一个网站 node.js (next.js),当我们通过控制台构建和启动(npm run build 和 npm start)时,他的网站运行良好。

我们将它托管在 Azure VM 中(安装了 Windows Server 2016 IIS、iisnode 和 urlrewrite),我们创建了一个管道,我们能够获取工件(运行构建时的“.next”文件夹)并部署它到 IIS 但是我们仍然需要手动交互来放置 web.config。下面是web.config

<!-- indicates that the hello.js file is a node.js application 
to be handled by the iisnode module -->

<handlers>
  <add name="iisnode" path="service-worker.js" verb="*" modules="iisnode" />
</handlers>

<!-- use URL rewriting to redirect the entire branch of the URL namespace
to hello.js node.js application; for example, the following URLs will 
all be handled by hello.js:

    http://localhost/node/express/myapp/foo
    http://localhost/node/express/myapp/bar

-->

<rewrite>
  <rules>
    <rule name="AMS" stopProcessing="true">
      <match url=".*" />
      <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
      </conditions>
      <action type="Rewrite" url="/" />
    </rule>
  </rules>
</rewrite> 

但是当我们访问该网站时,它会抛出一个需要提供默认页面的 403 错误。 (我迷路了,无法通过 IIS 运行他的网站)

注意:他的另一个网站运行良好(因为它有一个 service-worker.js)。

任何人都有将 Next.JS 部署到 IIS 的经验?提前致谢。

【问题讨论】:

  • 嘿伙计,你有什么运气吗?
  • @Terkhos,对不起伙计,我们删除了项目中的 next.js。我们只坚持在 nodejs 中。
  • 别担心,伙计。你现在用什么做 SSR?

标签: node.js iis next.js iisnode


【解决方案1】:

在 /public 文件夹中,创建以下 web.config 以接受来自 /a/b/c 的请求并将它们重写到 / 我们的 NextJs 代码所在的位置。

<?xml version="1.0"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="NextJs Routes" stopProcessing="true">
                    <match url=".*" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />                            
                    </conditions>
                    <action type="Rewrite" url="/" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

这样做应该可以让您在 /products 之类的路由上重新加载页面,但 NextJs 将呈现 /,即索引页面,因为这是我们的重写规则告诉它交付的内容。

所以,我们需要创建一个主体组件,它以 NextRouter 作为道具,然后将窗口的 url 与路由器的 url 进行比较。如果它们不匹配,我们需要使用router.push() 更改我们的客户端路由。

我正在使用 TypeScript,所以我的 body.tsx

import * as React from 'react';
import { NextRouter } from 'next/router';

export default class Body extends React.Component<{router : NextRouter}>
{    
    componentDidMount()
    {        
        if (window.location.pathname == this.props.router.pathname) return;
        
        this.props.router.push(global.window.location.pathname);        
    }

    render = () => this.props.children;                
}

然后在 _app.tsx 中,我们只需要将 main Component 包裹在 Body Component 中即可。

import { useRouter } from 'next/router'
import Head from 'next/head';
import Body from '../src/components/elements/body';

function MyApp({ Component, pageProps }) {

    const router = useRouter();        
        
    return (
        <>
            <Head>                
                <title>NextJs on IIS</title>
            </Head>

            <Body router={router}>                                
                <Component {...pageProps} />                                
            </Body>
        </>
    )
}

export default MyApp

运行 npm run build,并将 /out 文件夹复制到您的 IIS 服务器。

【讨论】:

  • 您好,感谢您的出色解决方案,但是当page is not exist or unknown pathname 时,我正在无限循环页面刷新,因为它总是推动路径名甚至不存在。示例:我有两个页面“主页和关于”,但我在 url /xyzxyz 上输入然后它变成了刷新页面的循环,因为该页面不存在。我还不能解决这个问题。你有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 2021-09-17
  • 1970-01-01
  • 2021-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多