场景:
① 通过域名访问静态资源,通过index.html,例如localhost:3000。
② 通过另外的端口访问api接口,例如localhost:4000
备注:协议、域名或端口不一致,即会产生跨域资源访问问题。这是由浏览器的同源机制造成,通常会提示(Access-Control-Allow-Origin)等问题
以下通过一段简单的nodejs服务器端代码还原这个问题:
参考以下注释:
备注①:get简单请求跨域处理
备注②:复杂请求跨域处理(会发送预请求options)
备注③:处理携带cookie请求
// http/api.js // http.js const http = require("http"); const fs = require("fs"); const app = http.createServer((req, res) => { const { method, url } = req; console.log("url:", method, url); if (method == "GET" && url == "/") { fs.readFile("./index.html", (err, data) => { res.setHeader("Content-Type", "text/html"); res.end(data); }); } else if (method == "OPTIONS" && url == "/api/users") { // 备注③:处理携带cookie请求 res.setHeader("Access-Control-Allow-Credentials", "true"); // 备注②:复杂请求的预检请求处理 // 处理复杂请求,请求来源localhost:3000,headers携带x-Token res.writeHead(200, { "Access-Control-Allow-Origin": "http://localhost:3000", "Access-Control-Allow-Headers": "X-Token,Content-Type", "Access-Control-Allow-Methods": "POST, GET, OPTIONS" }); res.end(); } else if (method == "GET" && url == "/api/users") { console.log('cookie',req.headers.cookie) // 备注③:处理携带cookie请求 res.setHeader('Access-Control-Allow-Credentials', 'true'); res.setHeader('Set-Cookie', 'cookie1=va222;') // 备注①:以下这句的意思代表,这个接口除了允许当前接口4000端口访问外,还能允许来自3000端口的请求。 res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000"); // res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify([{ name: "tom", age: 20 }])); } else if (method === "POST" && url === "/api/save") { let reqData = []; let size = 0; req.on("data", (data) => { console.log(">>>req on", data); reqData.push(data); size += data.length; }); req.on("end", function () { console.log("end"); const data = Buffer.concat(reqData, size); console.log("data:", size, data.toString()); res.end(`formdata:${data.toString()}`); }); } else if (method === "POST" && url === "/api/upload") { } }); module.exports = app;
http/index.js var express = require('express') const app = express() app.use(express.static(__dirname + '/')) // http域名地址:localhost:3000 app.listen(3000) const api = require('./api') // 接口地址localhost:4000 api.listen(4000)
// http/index.html
最后:使用proxy代理(nodejs)可以使用当前本地端口转发跨域的接口请求,绕过接口跨域的限制。
评论区