从 Angular 2 客户端到 Node.js 服务器的 HTTP POST 请求

Posted

技术标签:

【中文标题】从 Angular 2 客户端到 Node.js 服务器的 HTTP POST 请求【英文标题】:HTTP POST request from Angular 2 client to Node.js server 【发布时间】:2017-07-31 19:56:32 【问题描述】:

我在向我的 Node.js 服务器发送 POST 请求时遇到了一个奇怪的问题。我也有一些 GET 听众,但他们工作得很好。因此,我尝试从 Angular 2 应用程序(端口 4200)向 Node.js 服务器(端口 443)发送一个简单请求,如下所示,但我收到一个错误:

XMLHttpRequest 无法加载 http://localhost:443/edit_comment。回复 预检请求未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“http://localhost:4200” 访问。

客户服务方法:

   public saveComment(id: number, comment: string) : Observable<Response> 
        let data         =  id: id, comment: comment ;
        let headers      = new Headers('Content-Type': 'application/json'); 
        let options      = new RequestOptions( headers: headers );


        return this.http.post('http://localhost:443/edit_comment', JSON.stringify(data), options)
            .map((res:Response) => res.json())
            .catch((error:any) => Observable.throw(error.json().error || 'Server error')); 
    

node.js 服务器 端(带有 express 库):

app.post('/edit_comment', (req, resp) => 
    console.log('blabla') //this log never displays
    resp.setHeader('Access-Control-Allow-Origin','*')
    resp.send(JSON.stringify('foo'))
);

问题是 app.post 回调函数似乎没有被调用,因为 console.log 没有在屏幕上显示“blabla”消息。

在这里,我的浏览器中还有来自开发者工具的请求和响应标头:

请求标头:

Accept:*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Cache-Control:no-cache
Connection:keep-alive
Host:localhost:443
Origin:http://localhost:4200
Pragma:no-cache
Referer:http://localhost:4200/testlinemonitor
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/56.0.2924.87 Safari/537.36

响应标头:

HTTP/1.1 200 OK
X-Powered-By: Express
Allow: POST
Content-Type: text/html; charset=utf-8
Content-Length: 4
ETag: W/"4-oCQ57CKdi+DnSwwWAjkjEA"
Date: Fri, 10 Mar 2017 12:49:41 GMT
Connection: keep-alive

问候

【问题讨论】:

预检请求选项 /edit_comment 应配置为发送正确的标头,就像在调用 POST /edit_comment 之前浏览器将调用 OPTIONS /edit_comment "No 'Access-Control-Allow-Origin' header is present on the requested resource"的可能重复 【参考方案1】:

您的后端无法响应 OPTIONS 调用。 如果您有跨源请求,浏览器总是会进行预检 OPTIONS 调用。然后如果成功,它会执行 GET 或 POST。 请在 Chrome 调试器中检查网络流量。

这是 ExpressJS 服务器 https://github.com/expressjs/cors 的包

【讨论】:

我安装了 cors,现在我的请求被 app.post “捕获”了,但是如何获取 POST 参数? req.body 为空 后端必须能够为 OPTIONS 调用返回正确的访问控制标头。在此处查看最后一段代码johnzhang.io/options-request-in-express 或使用 expressjs/cors 中的中间件包 好的,但现在我在获取 POST 参数时遇到了问题。似乎他们没有被发送或smth。 Req.body 是一个空字典 首先,打开 Chrome DevTools 并检查您是否正在发送developers.google.com/web/tools/chrome-devtools/… 我的对象在响应和请求标头下方有类似“请求有效负载”的内容【参考方案2】:

您不仅需要允许允许的来源,还需要允许方法和标头。

尝试添加允许 CORS 请求的标头:

res.setHeader('Access-Control-Allow-Origin', '*')

//Add as many Headers as you want to line below
//If you use "Authentication" Header, insert it like 'Content-type, Authentication'
res.setHeader('Access-Control-Allow-Headers', 'Content-type')

res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')

【讨论】:

你读过我的代码吗? :) 我设置了 Access-Control-Allow-Origin 标头。我什至添加了您提供的其余标题,但它不起作用

以上是关于从 Angular 2 客户端到 Node.js 服务器的 HTTP POST 请求的主要内容,如果未能解决你的问题,请参考以下文章

当我尝试从 Angular.js 发送到 Node.js 时,单独的数据丢失了

如何将数据从角度发送到node.js

如何从 Angular 6 向 node.js 发送 https 请求

Node.js 可写流创建错误文件(更大且不可读)

如何使用 Node.js 从 Angular 将日期插入 MySQL DATETIME 列?

使用 Sendgrid/Nodemailer 将 Angular 表单数据发布到 Node.js