nginx,node 解决跨域问题记录

324 阅读1分钟

demo 仓库地址

node repository: github.com/jakequc/cro…

react repository: github.com/jakequc/cro…

nginx 配置 请看 3. 修改 nginx.conf 配置

跨域经常是困扰初学者的一个问题,如果让你解决怎样跨域,也许你借助搜索引擎回得到很多中方法,有一种别是使用 nginx 来解决跨域,但是具体怎么解决跨域呢,也许文章作者也没有给你详细写解决方案,因此便有了此文。

说明: 该方法适用于 vue、react 等能通用前端服务资源,比如 访问 http://localhost:3000 便可以打开一个 page

跨域是啥

跨域就是不同域上访问了其他域而出现的问题(是浏览器的一种安全策略),如果端口、协议、域名出现一个不同,则会出现跨域;(如下页面前端应该都看到过),

跨域报错图

解决跨域的步骤

  1. 启动你的页面,通常 react 等项目是使用 npm run startyarn start;知道你需要请求的地址,此demo的地址是 node 起的一个服务;真实请求的服务地址是 <http://localhost:8000>

image.png

const express = require("express");
const Mock = require("mockjs");
const app = express();

app.get("/", function (req, res) {
  res.send("Hello World");
});

app.post("/api/post", (_, res) => {
  res.send(
    Mock.mock({
      msg: "@name",
      success: "@boolean",
      text: "post",
    })
  );
});

app.get("/api/get", (_, res) => {
  res.send(
    Mock.mock({
      msg: "@name",
      success: "@boolean",
      text: "get",
    })
  );
});

const port = 8000;
app.listen(port, () => {
  console.log(`express server starting at: http:127.0.0.1:${port}`);
});

  1. 安装 nginx

    自己去搜索吧

  2. 修改 nginx.conf 配置

# 大概是这样的,说明: 如下只是一个模板
  server {
    listen nginxPort; # nginx 服务的端口号
    server_name nginxServerName; # nginx 的服务名称

    location / {
      root html;
      index index.html index.htm;
    }

    location ~ ^/api {
      add_header Access-Control-Allow-Origin '可以访问 http://${nginxServerName}:${nginxPort} 的 origin';
      add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
      root html;
      proxy_pass "请求的最终服务地址";
    }
  
     xxx.....
  }
worker_processes 1;

events {
  worker_connections 1024;
}


http {
  include mime.types;
  default_type application/octet-stream;

  sendfile on;

  keepalive_timeout 65;


  server {
    listen 8080;
    server_name localhost; # server_name 和 listen 表明你的 nginx 服务跑再 http://localhost:8080 服务上

    location / {
      root html;
      index index.html index.htm;
    }

    # 这里~表示精准匹配 访问 /api/xxx 的请求,比如 http://localhost:8080/api/xxx 
    location ~ ^/api {
        # http://127.0.0.1:3000 是你本地或者前端托管资源 origin,页面访问的时候就需要使用 127.0.0.1 而不是 localhost 了
  	add_header Access-Control-Allow-Origin http://127.0.0.1:3000;
        add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
        root html;
         # 如下两行是解决 post 请求出现 has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
	 add_header Access-Control-Allow-Headers Origin,X-Requested-With,Content-Type,Accept;
	 add_header Content-Type "application/json;charset=utf-8";
     	 # proxy_pass 代表你真实请求的 服务端地址
      	 proxy_pass http://localhost:8000;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
      root html;
    }
  }

  include servers/*;
}
  1. 前端请求 nginx 的服务名 + 对应的url (注意不是直接请求的地址)

比如请求 http://localhost:8080/api/get 数据

const baseURL = "http://localhost:8080";

const App = () => {
  const [data, setData] = useState();
  const [method, setMethod] = useState("get");

  const getRequest = () => {
    setMethod("get");
    get(`${baseURL}/api/get`).then((res) => setData(res));
  };

  const postRequest = () => {
    setMethod("post");
    post(`${baseURL}/api/post`).then((res) => setData(res));
  };

  return (
    <div className="App">
      <button onClick={getRequest}>get request</button>
      <br />
      <br />
      <button onClick={postRequest}>postRequest</button>

      <div>
        <br />
        {method} : {data}
      </div>
    </div>
  );
};

通过我们启动的页面地址:http://127.0.0.1:3000 (而不是http://localhost:3000) 去页面请求服务最终成功: image.png