.htaccess服务器端路由和节点环境重定向

huangapple go评论79阅读模式
英文:

.htaccess server-side routing and node environment redirects

问题

I have a React webapp with a Node.js server, the .htaccess file of my website used to redirect the webpages requests to index.html this however meant that the emails being sent from the forms on the site were not being delivered since the requests had to be redirected to the Node Environment. This was fixed by redirecting the requests to the Node Environment instead of the index.html inside my .htaccess file, however, this means that my server-side routing now broke and I am now getting the Cannot GET /end-point error whenever I type in the URL with an end-point in the browser window or if I refresh the page.

old .htaccess:

RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]

current .htaccess:

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Is there a fix without either breaking my server-side routing or email delivering?

Edit:

server.js:

const express = require("express");
const app = express();
require("dotenv").config({path: "../.env"});
const bodyParser = require("body-parser");
const cors = require("cors");
const nodemailer = require("nodemailer");
var sgTransport = require('nodemailer-sendgrid-transport');
const multer = require("multer");

app.use(express.urlencoded({extended: true}));
app.use(express.json());

app.use(cors());

const transport = nodemailer.createTransport(sgTransport({
  auth: {
    api_key: process.env.SG_API_KEY
  }
}));

app.post("/send_schools_form", cors(), async (req, res) => {
  let {
    school,
    address,
    name,
    phone,
    email,
    substitutes
  } = req.body;

  var substitutesList = substitutes.reduce(function(a, b) {
  return a + '</br><ul><li>Startdatum: ' + b.date + '</li><li>Tid: ' + b.time + '</li>    <li>Info: ' + b.info + '</li></ul>';
}, '');

  await transport.sendMail({
    from: process.env.USER_SENDER,
    to: process.env.USER_RECEIVER,
    subject: `Vikarie begäran ${school}`,
    html: `
    <ul>
      <li>Skola: ${school}</li>
      <li>Adress: ${address}</li>
      <li>Kontaktperson: ${name}</li>
      <li>Telefon: ${phone}</li>
      <li>E-post: ${email}</li>
    </ul>
    <ul>${substitutesList}</ul>
    `
  }, (err) => {
    if (err) {
      console.log(err);
      res.status(400).send('Error');
    } else {
      res.status(200).send('Success');
    }
  })
});

const upload = multer({
  storage: multer.memoryStorage()
});

let middleware = [
  cors(),
  upload.fields([
    {name: "cvFile", maxCount: 1},
    {name: "otherFile", maxCount: 1}
  ])
];

app.post("/send_substitutes_form", middleware, async (req, res) => {
  let {
    firstName,
    lastName,
    email,
    phone,
    address,
    city,
    postalCode,
    availability
  } = req.body;

  await transport.sendMail({
    from: process.env.USER_SENDER,
    to: process.env.USER_RECEIVER,
    subject: `Arbetsansökan ${firstName} ${lastName}`,
    html: `
    <ul>
      <li>Namn: ${firstName} ${lastName}</li>
      <li>E-post: ${email}</li>
      <li>Telefon: ${phone}</li>
      <li>Adress: ${address}</li>
      <li>Ort: ${city}, ${postalCode}</li>
      <li>Tillgänglighet: ${availability} dagar per vecka</li>
    </ul>
    `,
    attachments: [{
      filename: req.files["cvFile"][0].originalname,
      content: req.files["cvFile"][0].buffer
    },
    {
      filename: req.files["otherFile"][0].originalname,
      content: req.files["otherFile"][0].buffer
    }]
  }, (err) => {
    if (err) {
      console.log(err);
      res.status(400).send('Error');
    } else {
      res.status(200).send('Success');
    }
  })
});

const PORT = process.env.PORT || 4000;

app.listen(PORT, () => {
  console.log("Server is listening on port " + PORT);
});
英文:

I have a React webapp with a Node.js server, the .htaccess file of my website used to redirect the webpages requests to index.html this however meant that the emails being sent from the forms on the site were not being delivered since the requests had to be redirected to the Node Environment. This was fixed by redirecting the requests to the Node Environment instead of the index.html inside my .htaccess file, however, this means that my server-side routing now broke and I am now getting the Cannot GET /end-point error whenever I type in the URL with an end-point in the browser window or if I refresh the page.

old .htaccess:

RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]

current .htaccess:

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Is there a fix without either breaking my server-side routing or email delivering?

Edit:

server.js:

const express = require(&quot;express&quot;);
const app = express();
require(&quot;dotenv&quot;).config({path: &quot;../.env&quot;});
const bodyParser = require(&quot;body-parser&quot;);
const cors = require(&quot;cors&quot;);
const nodemailer = require(&quot;nodemailer&quot;);
var sgTransport = require(&#39;nodemailer-sendgrid-transport&#39;);
const multer = require(&quot;multer&quot;);
app.use(express.urlencoded({extended: true}));
app.use(express.json());
app.use(cors());
const transport = nodemailer.createTransport(sgTransport({
auth: {
api_key: process.env.SG_API_KEY
}
}));
app.post(&quot;/send_schools_form&quot;, cors(), async (req, res) =&gt; {
let {
school,
address,
name,
phone,
email,
substitutes
} = req.body;
var substitutesList = substitutes.reduce(function(a, b) {
return a + &#39;&lt;/br&gt;&lt;ul&gt;&lt;li&gt;Startdatum: &#39; + b.date + &#39;&lt;/li&gt;&lt;li&gt;Tid: &#39; + b.time + &#39;&lt;/li&gt;    &lt;li&gt;Info: &#39; + b.info + &#39;&lt;/li&gt;&lt;/ul&gt;&#39;;
}, &#39;&#39;);
await transport.sendMail({
from: process.env.USER_SENDER,
to: process.env.USER_RECEIVER,
subject: `Vikarie beg&#228;ran ${school}`,
html: `
&lt;ul&gt;
&lt;li&gt;Skola: ${school}&lt;/li&gt;
&lt;li&gt;Adress: ${address}&lt;/li&gt;
&lt;li&gt;Kontaktperson: ${name}&lt;/li&gt;
&lt;li&gt;Telefon: ${phone}&lt;/li&gt;
&lt;li&gt;E-post: ${email}&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;${substitutesList}&lt;/ul&gt;
`
}, (err) =&gt; {
if (err) {
console.log(err);
res.status(400).send(&#39;Error&#39;);
} else {
res.status(200).send(&#39;Success&#39;);
}
})
});
const upload = multer({
storage: multer.memoryStorage()
});
let middleware = [
cors(),
upload.fields([
{name: &quot;cvFile&quot;, maxCount: 1},
{name: &quot;otherFile&quot;, maxCount: 1}
])
];
app.post(&quot;/send_substitutes_form&quot;, middleware, async (req, res) =&gt; {
let {
firstName,
lastName,
email,
phone,
address,
city,
postalCode,
availability
} = req.body;
await transport.sendMail({
from: process.env.USER_SENDER,
to: process.env.USER_RECEIVER,
subject: `Arbetsans&#246;kan ${firstName} ${lastName}`,
html: `
&lt;ul&gt;
&lt;li&gt;Namn: ${firstName} ${lastName}&lt;/li&gt;
&lt;li&gt;E-post: ${email}&lt;/li&gt;
&lt;li&gt;Telefon: ${phone}&lt;/li&gt;
&lt;li&gt;Adress: ${address}&lt;/li&gt;
&lt;li&gt;Ort: ${city}, ${postalCode}&lt;/li&gt;
&lt;li&gt;Tillg&#228;nglighet: ${availability} dagar per vecka&lt;/li&gt;
&lt;/ul&gt;
`,
attachments: [{
filename: req.files[&quot;cvFile&quot;][0].originalname,
content: req.files[&quot;cvFile&quot;][0].buffer
},
{
filename: req.files[&quot;otherFile&quot;][0].originalname,
content: req.files[&quot;otherFile&quot;][0].buffer
}]
}, (err) =&gt; {
if (err) {
console.log(err);
res.status(400).send(&#39;Error&#39;);
} else {
res.status(200).send(&#39;Success&#39;);
}
})
});
const PORT = process.env.PORT || 4000;
app.listen(PORT, () =&gt; {
console.log(&quot;Server is listening on port &quot; + PORT);
});

答案1

得分: 1

你做错了,不应该使用301重定向。

我假设你是通过向后端发送HTTP请求来发送电子邮件,所以你需要将后端的所有路径设置为特定路径,如/api。然后,你可以使用以下答案来解决你的问题:

RewriteEngine on

RewriteCond %{REQUEST_URI} ^/api/
RewriteRule (.*) /api/public/index.php [L]

RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]

查看这个这个链接。

英文:

You are doing it wrong, you should not redirect with 301.

I'm assuming you are sending an email by post an http request to your backend, so you need to set all your backend with specific path like /api. Then you could use this answers to solve your problem:

RewriteEngine on
RewriteCond %{REQUEST_URI} ^/api/
RewriteRule (.*) /api/public/index.php [L]
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]

Check this and this

答案2

得分: 0

问题已通过在我的 server.js 文件底部添加此“捕获所有”路由来解决,位于将请求发送到发送电子邮件的其他路由之后。

app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, '/path/to/index.html'));
});

这样做的话,它只会在之前的路由都不匹配请求时执行。

另外,不要忘记在顶部添加 path 的导入语句:

const path = require("path");
英文:

The issue was solved by adding this "catch-all" route near the bottom of my server.js file, after the other routes that post the requests to send the emails.

app.get(&#39;*&#39;, (req, res) =&gt; {
res.sendFile(path.join(__dirname, &#39;/path/to/index.html&#39;));
});

This way, it will only be executed if none of the previous routes matches the request.

Also don't forget the import statement for path at the top:

const path = require(&quot;path&quot;);

huangapple
  • 本文由 发表于 2023年1月6日 16:41:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75028668.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定