添加应用程序/json 后,跨域请求被阻止出错
Posted
技术标签:
【中文标题】添加应用程序/json 后,跨域请求被阻止出错【英文标题】:Cross-Origin Request Blocked erroring out after adding application/json 【发布时间】:2018-11-30 20:25:00 【问题描述】:我正在尝试使用 React 向 Node 发送一些数据。这是我的反应代码:
sendMail(e)
e.preventDefault();
// fetch('/https://uczsieapp-mailer.herokuapp.com/',
var name = document.getElementById('name').value;
var contactReason = document.getElementById('contactReason').value;
var email = document.getElementById('email').value;
var additionalInfo = document.getElementById('additionalInfo').value;
var body =
name: name,
contactReason: contactReason,
email: email,
additionalInfo: additionalInfo,
;
body = JSON.stringify(body);
console.log(body);
fetch('http://localhost:4000/',
method: 'POST',
headers:
'Accept': 'application/json',
'Content-Type': 'application/json',
,
content: body,
).then(r => console.log(r)).catch(e => console.log(e));
这是我的节点代码:
var cors = require('cors');
var app = express();
app.use(cors());
var a = '=';
router.post('/', (req, res, next) =>
console.log('mailing');
console.log(a);
a += '=';
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport(
host: "smtp.gmail.com", // hostname
auth:
user: 'someuser@gmail.com',
pass: 'testgmail'
);
console.log(req.body.content);
let mailOptions =
from: `$req.body.name $req.body.email`, // sender address
to: 'alexander.ironside@mygeorgian.ca', // list of receivers
subject: 'Email from UczSieApp contact form', // Subject line
text: 'Hello world ', // plaintext body
html: `
<h4>Imie: $req.body.name</h4>
<h4>Email: $req.body.email</h4>
<h4>Powod kontaktu: $req.body.contactReason</h4>
<p>Wiadomosc: $req.body.additionalInfo</p>
`
;
// send mail with defined transport object
transporter.sendMail(mailOptions, function (error, info)
if (error)
return console.log(error);
console.log('Message sent: ' + info.response);
);
);
如您所见,我正在使用cors module,它应该可以处理所有cors
问题。
但这还不够。当我摆脱传递给fetch()
的headers
属性时,调用正在完成,但没有发送数据。当我添加headers
时,我得到了乐趣
跨域请求被阻止:同源策略不允许读取位于http://localhost:4000/ 的远程资源。 (原因:CORS 标头“Access-Control-Allow-Origin”缺失)。
又报错了。
我怎样才能绕过它,我错过了什么?
我在编写代码时使用了这个答案:https://***.com/a/42965820/7055769
【问题讨论】:
CORS 是出于安全原因,考虑到 cors 代码(希望)不会部署到生产环境中,我认为采用另一种方法要好得多,例如安装 nginx(或apache,或码头或任何其他可以反向代理您的呼叫的服务器)本地并将您的呼叫从前端服务器代理到快速服务器。 我只想从网站发送一封电子邮件。该数据库基于 Firebase,因此 Node 将无法连接到数据库。 CORS 发生在客户端(您的反应应用程序)和服务器(您的快递)之间。您想根据我在您的代码中看到的内容从服务器发送电子邮件,所以我的建议仍然适用。 【参考方案1】:事实证明,CORS 只允许某些特定的内容类型。
Content-Type 标头的唯一允许值是:
-
application/x-www-form-urlencoded
多部分/表单数据
文本/纯文本
origin 参数指定一个可以访问资源的 URI。浏览器必须强制执行此操作。对于没有凭据的请求,服务器可以将“*”指定为通配符,从而允许任何来源访问资源。
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
fetch('http://localhost:4000/',
method: 'POST',
mode: 'cors',
headers:
'Access-Control-Allow-Origin': '*',
'Accept': 'application/json',
'Content-Type': 'application/json',
,
content: body,
).then(response => response.json()).then(r => console.log(r)).catch(e => console.log(e));
【讨论】:
如果只允许3种类型,我不应该改变Content-Type
的类型吗?
Access-Control-Allow-Origin
设置在服务器的响应上,让浏览器知道哪些域可以访问它。在请求上设置它不会做任何事情。 javascript 无法绕过 CORS。如果可以,那将是一个毫无意义的安全机制。此标头必须由服务器在响应中设置。
@Taplar 但是服务器没有发送任何响应【参考方案2】:
您介意按以下方式尝试,这应该可以解决问题:
app.use(function (req, res, next)
//set headers to allow cross origin requestt
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
);
【讨论】:
【参考方案3】:好的,有很多原因这不起作用。我将这个答案留给未来的开发者以减轻他们的痛苦。
这是在客户端工作的方法:
$.ajax(
type: "POST",
url: 'http://localhost:4000/',
data: body,
success: data=>console.log(data),
dataType: 'json',
);
这是我的整个服务器端代码:
var express = require('express');
var router = express.Router();
var cors = require('cors');
var app = express();
app.use(cors());
app.options('*', cors());
var a = '=';
router.post('/', (req, res, next) =>
console.log('mailing');
console.log(a);
a += '=';
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport(
host: "smtp.gmail.com", // hostname
auth:
user: 'sqtableknights@gmail.com',
pass: 'testgmail'
);
console.log(req.body);
let mailOptions =
from: `$req.body.name $req.body.email`, // sender address
to: 'alexander.ironside@mygeorgian.ca', // list of receivers
subject: 'Email from UczSieApp contact form', // Subject line
text: 'Hello world ', // plaintext body
html: `
<h4>Imie: $req.body.name</h4>
<h4>Email: $req.body.email</h4>
<h4>Powod kontaktu: $req.body.contactReason</h4>
<p>Wiadomosc: $req.body.additionalInfo</p>
`
;
// send mail with defined transport object
transporter.sendMail(mailOptions, function (error, info)
if (error)
return console.log(error);
console.log('Message sent: ' + info.response);
);
);
module.exports = router;
所以在我的情况下,我必须添加这些:
app.use(cors());
app.options('*', cors());
不知道为什么,但它只是在没有app.options('*', cors());
参数的情况下中断。如果有人对此有更好的答案,和/或发现任何安全漏洞,请发表评论并告诉我。再次感谢大家的帮助!
【讨论】:
以上是关于添加应用程序/json 后,跨域请求被阻止出错的主要内容,如果未能解决你的问题,请参考以下文章