跨域对于前端来说是一个老大难的问题,许多方法如jsonpdocument.domain + iframe...都有或多或少的问题,一个最佳实践就是通过服务器nginx做反向代理,但奈何不懂相关知识,就一直琢磨着使用 node.js来做。

 

  之前公司php写的接口,然后用node定义一样的路由,前端请求node的接口,然后通过Node在控制器中访问php的接口,这样确实能解决跨域问题,不过也是有缺点的,不能带上cookic等信息,不等同于反向代理;

  

  事实上使用node是可以很容易构建本地的反向代理,使用 http-proxy-middleware 模块

  假如目前有一个php提供的接口为   http://api.text.com/getdata  需要去代理

  首先

npm i  http-proxy-middleware --save   //反向代理包
npm i cors  --save            //node跨域模块 

 然后:生成一个新的 express,app.js里面 删掉 index和user这两个路由,然后

var cors = require('cors');
var proxy = require('http-proxy-middleware');
var options = {
target: 'http://api.text.com', // 目标主机,提供接口服务的域名
changeOrigin: true, // 需要虚拟主机站点
};
var exampleProxy = proxy(options); //开启代理功能,并加载配置

  

app.use(cors());

app.use(exampleProxy);  //代理任意请求的路由,也可以改成代理固定的某些路由

启动express服务

前段代码:

const host = "http://127.0.0.1:3000";
$.ajax({
url: host+ "/getdata"
}).then(function(data){
console.log(data);
}).fail(function(error){
console.log(error);
});

目前为止,反向代理成功,本地电脑可以跨域访问远程服务接口

另外,附加上,自己写的一个,携带cookic 的转发:

roouter.js 文件

var express = require('express');
var router = express.Router();
var request = require("request");
/* GET home page. */ const Api = {
GET(params){
params = params || {};
return new Promise(function(resolve,reject){
request({
method:"GET",
url:params.url,
qs:params.data,
headers:params.headers
},function (error, response, body) {
if (!error) {
resolve({response,body});
}else{
reject(error);
}
});
}) },
POST(params){
params = params || {};
return new Promise(function(resolve,reject){
request({
method:"POST",
url:params.url,
form:params.data,
headers:params.headers
},function (error, response, body) {
if (!error) {
resolve({response,body});
}else{
reject(error);
}
});
})
}
} module.exports = function(opt){
opt = opt || {};
var target = opt.target || '';
var url = opt.url || "**";
router.all(url,function(req,res,next){
var url = target + req.baseUrl + req.path;
var data = {};
var method = req.method;
if(method =="GET"){
data = req.query;
}else if(method == "POST"){
data = req.body;
}
let Cookie = req.header("Cookie");
let content = req.header('Content-type');
console.log("url:"+url,data,Cookie,content);
data.headers = {
"content-type": content,
"Cookie":Cookie
};
if(Api[req.method]){
Api[req.method]({
url:url,
data:data
}).then(function({response,body}){
try{
body = JSON.parse(body);
}catch(e){
}
// ************** 透传响应中的cookie **************
if (response.headers['set-cookie']) {
res.setHeader("set-cookie", response.headers['set-cookie']);
} // ************** 自定义cookie **************
//res.cookie('tc', 'test-cookie', {maxAge: 2 * 60 * 60 * 1000, httpOnly: true}); return res.status(response.statusCode).send(body);
//return res.json(body);
}).catch(function(e){
res.json(e);
})
}else{
res.json({code:500,msg:"不支持的请求类型"});
}
})
return router;
};

  

  

index.js

var express = require('express');
var router = require("./routers"); var cors = require('cors'); var app = express(); app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cors()); var config = {
target:"http://xxxxxx"
}; app.use("/",router(config)); app.listen("3000",function(error){
console.log("启动服务-----3000");
})

  

koa2 版本

const router = require('koa-router')()

var request = require("request");
/* GET home page. */ const Api = {
GET(params){
params = params || {};
return new Promise(function(resolve,reject){
request({
method:"GET",
url:params.url,
qs:params.data
},function (error, response, body) {
if (!error && response.statusCode == 200) {
try{
body = JSON.parse(body);
} catch(e){ }
resolve(body);
}else{
reject(error);
}
});
}) },
POST(params){
params = params || {};
return new Promise(function(resolve,reject){
request({
method:"POST",
url:params.url,
form:params.data
},function (error, response, body) {
if (!error && response.statusCode == 200) {
try{
body = JSON.parse(body);
} catch(e){ }
resolve(body);
}else{
reject(error);
}
});
})
}
} module.exports = function(opt){
opt = opt || {};
var target = opt.target || '';
var url = opt.url || "**";
if(opt.prefix){
router.prefix(opt.prefix)
}
router.all(url,async function(ctx,next){
var url = target + ctx.path; var data = {};
if(ctx.method =="GET"){
data = ctx.query;
}else if(ctx.method == "POST"){
data = ctx.request.body;
}
console.log("请求来源:"+url,data,ctx.method);
if(Api[ctx.method]){
try{
ctx.body = await Api[ctx.method]({
url:url,
data:data
});
}catch(e){
ctx.body = e;
} }else{
ctx.body = {code:500,msg:"不支持的请求类型"};
}
})
return router;
};

  

 

使用:

const proxy = require('./routers');

const insproxy = proxy({
target:"xxxx",
prefix:"/xxx"
}); app.use(insproxy.routes(), insproxy.allowedMethods());

  

解决异地服务器接口访问跨域,node构建反向代理的更多相关文章

  1. Vue解决接口访问跨域问题

    随手摘录 Vue解决接口访问跨域问题 1.打开 config -> index.js 2. 找到proxyTable 3.粘贴 如下代码,'https://www.baidu.com'换成要访问 ...

  2. nodejs服务实现反向代理,解决本地开发接口请求跨域问题

    前后端分离项目需要解决第一个问题就是,前端本地开发时如何解决通过ajax请求产生的跨域的问题.一般的做法是通过本地配置nginx反向代理进行处理的,除此之外,还可以通过nodejs来进行代理接口.当然 ...

  3. vue脚手架解决跨域问题-------配置反向代理

    1.打开config/index.js 2.在dev配置对象中找到proxyTable:{} 3.添加如下配置 // 配置反向代理,解决跨域请求 proxyTable: { '/api': { tar ...

  4. CORS跨域与Nginx反向代理跨域优劣对比

    最近写了一些关于前后端分离项目之后,跨域相关方案的基本原理和常见误区的帖子,主要包括CORS和Nginx反向代理.这两种方案项目中都有在用,各有优缺,关于具体使用哪种方案,大家的观点也不大一致,本文主 ...

  5. 跨域问题 - Nginx反向代理

    Nginx反向代理的思路,就是通过Nginx解析URL地址的时候进行判断,将请求转发的具体的服务器上. 解决思路 跨域问题,是由于JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象. ...

  6. vue 解决axios请求出现前端跨域问题

    vue 解决axios请求出现前端跨域问题 最近在写纯前端的vue项目的时候,碰到了axios请求本机的资源的时候,出现了访问报404的问题.这就让我很难受.查询了资料原来是跨域的问题. 在正常开发中 ...

  7. 解决 net core 3.x 跨域问题

    跨域:指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制. 以下几种情况是造成跨域的原因: 域名相同,端口不同 域名相同,协议不同(即,一个 ...

  8. 简单设置,解决使用webpack前后端跨域发送cookie的问题

    最近用vue来做项目,用webpack来做前端自动化构建.webpack-dev-server会在本地搭建一个服务器,在和后端调试的时候,就会涉及到跨域的问题. 刚开始时,没有用vue-cli来构建项 ...

  9. 「Django」rest_framework学习系列-API访问跨域问题

    #以中间件方式解决API数据访问跨域问题1.API下新建文件夹下写PY文件a.引入内置类继承: from django.middleware.common import MiddlewareMixin ...

随机推荐

  1. RasterEdge.DocImageSDK9.8.7 破解版

    RasterEdge.DocImageSDK9.8.7 破解版 本人破解了 RasterEdge.DocImageSDK9.8.7 ,有需要的同学请联系本人.

  2. 如何从视频中分离出音乐,和对音乐做分割,合并的处理(瑞典音乐家-新八宝盒.mp3.rar下载)

    点击下载:瑞典音乐家-新八宝盒.mp3.rar 1.工具 Total Video Converter 3.71 视频处理(安装软件,有绿色版的) MP3剪切器 MP3剪切器(小工具) Mp3mateP ...

  3. 配置hadoop集群,完全分布式模式

    [/soft/hadoop/etc/hadoop] [hdfs-site.xml] <configuration> <property> <name>dfs.rep ...

  4. mo +离散化 HDU3333(听说还有离线线段树的做法 )

    http://acm.hdu.edu.cn/showproblem.php?pid=3333 mo套map会T,卡了一个logN,所以要先离散化处理 #define _CRT_SECURE_NO_WA ...

  5. role="navigation"

    HTML5的标签属性,可以用于标识一个普通的标签,使之语义化,方便浏览器对其具体功能进行识别. 例如div容器制作的导航栏,加上role="navigation",就可以让浏览器知 ...

  6. 一道与时间差有关的SQL面试题

    题目: 一组通话记录(总共500万条):ID 主叫号码 被叫号码 通话起始时间 通话结束时间 通话时长1 98290000 0215466546656 2007-02-01 09:49:53.000 ...

  7. 关于Java程序流程控制的整理(已完善)

  8. day0311 深浅copy

    1.赋值运算 l1 = [1,2,3,['barry','alex']] l2 = l1 l1[0] = 111 print(l1) # [111, 2, 3, ['barry', 'alex']] ...

  9. Servlet----------Servlet 概述

    1.什么是Servlet Servle t是Java Web 的三大组件之一,它属于动态资源.Servlet 的作用是处理请求,服务器会把接收到时的请求交给 Servlet 来处理,在Servlet中 ...

  10. 关于linux下mysql安装和卸载

    卸载:https://www.cnblogs.com/Lenbrother/articles/6203620.html 卸载Mysql 找到了这篇文章:http://zhangzifan.com/ce ...