【问题标题】:Cross-Origin Request Blocked even after adding headers in server code即使在服务器代码中添加标头后,跨域请求也被阻止
【发布时间】:2021-03-23 14:10:25
【问题描述】:

我在 Express/Node 中有一个简单的 API,还有一个用于发布博客的简单 Angular 应用程序。唯一的问题是当我使用 POST 方法访问 /contribute 路由时。我在 chrome 和 firefox 上都遇到了这个错误:

错误:错误{目标:XMLHttpRequest,isTrusted:true,lengthComputable:false,...} ​​​ 标头:对象 { normalizedNames:地图(0),lazyUpdate:空,标头:地图(0)} ​​​ 消息:“本地主机的 Http 失败响应:3000/api/contribute:0 未知错误” ​​​ 名称:“HttpErrorResponse” ​​​ 好的:假的 ​​​ 状态:0 ​​​ statusText:“未知错误” ​​​ 网址:“本地主机:3000/api/contribute” ​​​ :{…} ​​​​ 构造函数:类 HttpErrorResponse { 构造函数(init) }​​​ :{…} ​​​​ 构造函数:类 HttpResponseBase { 构造函数(init, defaultStatus, defaultStatusText) }​​​​ :{…

这是我的服务器端代码。

api.js

...
router.post('/contribute', (req, res) => {
    console.log('Pushing new article');
    let userPost = req.body;
    let post = new Post(userPost);
    post.save((error, registeredPost) => {
        if (error) {
            console.log(error);
        } else {
            res.status(200).send(registeredPost);
        }
    })
})
...
module.exports = router;

server.js

const express = require('express');
const bodyParser = require('body-parser');

const app = express();

const api = require('./routes/api');
const cors = require('cors');

app.use(bodyParser.json());

// app.use(cors({ origin: 'http://localhost:4200' })); <--- TRIED THIS ALSO

app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});

app.use('/api', api);
app.get('/', function(req, res) {
    res.send('Server is up and running!');
})

app.listen(3000, function() {
    console.log('Server listening port:3000');
});

是的,服务器已启动并正在运行。

这里是角码。 auth.service.ts

private _contributeUrl = "https://localhost:3000/api/contribute";
...
pushNewPost(newPost) {
  console.log("here is the new post", newPost); // GETTING CORRECT OUTPUT
  return this._http.post<any>(this._contributeUrl, newPost);
}

contribute.component.ts

this._auth.pushNewPost(this.makeNewPost)
.subscribe (
  res => {
    (<HTMLInputElement>document.getElementById("inputTitle")).value="";
    this.editorForm.reset();
    this.addSingle();
  },
  err => console.log(err)
);

现在有趣的部分是,当我使用 Postman 向这条路线发出发布请求时,相同的代码可以完美运行,没有任何错误。

请纠正我的错误。添加后:

  pushNewPost(newPost) {
    console.log("here is the new post", newPost);
    let headers = new HttpHeaders({
      'Content-Type': 'application/json',
     });
     let options = { headers: headers };
    return this._http.post<any>(this._contributeUrl, newPost);
  }

我明白了:

【问题讨论】:

  • 对于private _contributeUrl = "https://localhost:3000/api/contribute";中的本地API,不应该只是http而不是https吗?
  • 当然@NicholasK,实际上我的技术主管仍在审查它。但它正在工作,所以我现在接受它。抱歉耽搁了。我很抱歉。
  • @NicholasK,实际上我的 api 并没有在 localhost 上运行。只是为了诊断错误,我在本地拉了那个分支。实际的服务器部署在这里。obscure-tundra-38074.herokuapp.com它的运行你可以交叉检查
  • @NicholasK,当我更改 private _contributeUrl = "https://obscure-tundra-38074.herokuapp.com/api/contribute"; 时,我开始遇到同样的错误。
  • HttpErrorResponse {headers: HttpHeaders, status: 500, statusText: "Internal Server Error", url: "obscure-tundra-38074.herokuapp.com/api/contribute", ok: false, …}

标签: node.js angular express


【解决方案1】:

似乎您没有从角度发送标题。进行以下更改:

pushNewPost(newPost) {
  // adding the headers
  const headers = new HttpHeaders({
   'Content-Type': 'application/json',
  });
  const options = { headers: headers };

  return this._http.post<any>(this._contributeUrl, newPost, options);
}

【讨论】:

  • 我正在添加有问题的屏幕截图。
  • 对我来说似乎更像是一个后端问题。
  • 好的。给我一些时间。让我对此进行更多探索。我会尽快给您回复。请随时提醒我这个悬而未决的问题。 :-)
  • 嗨 Nicholas,我自己想出了一些办法。首先,在 *server.js 中,我将 res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200'); 更改为 res.setHeader('Access-Control-Allow-Origin', '*');。然后我也意识到我犯了一个非常愚蠢的错误。我忘了在... return this._http.post&lt;any&gt;(this._contributeUrl, newPost, options); 中传递option。所以现在代码正在工作。但我想知道我是否必须在所有其他请求中传递标头,因为我至少有 15 个不同的调用,如更新、删除、upvote、downvote、重复等。请指导我。
  • aaaahhh...现在我明白拦截器的目的了。实际上我已经有一个令牌拦截器服务。无论如何,推到分支,现在提出拉取请求。 :-) 谢谢
猜你喜欢
  • 1970-01-01
  • 2018-06-13
  • 2018-11-05
  • 1970-01-01
  • 2016-01-21
  • 2020-05-06
  • 2017-06-06
  • 2019-09-10
  • 2021-06-26
相关资源
最近更新 更多