1. 需求背景

公司网站的本地开发版之前一直都是部署在本地电脑上Tomcat容器里的,好处就是本地搭建服务器环境接口无需做跨域请求处理,坏处就是后台代码的每次更新都需要拷贝一份至我的电脑覆盖,并且本地环境与测试线环境数据仍然有所差异,在本地环境调试不便。

前天在与新入职的Java工程师讨论如何分工协作的时候聊到了部署Tomcat容器到我本地的坏处,然后仔细想想我最近不是在学nodejs嘛,为何不学以致用在我本地用nodejs部署跨域代理服务呢?于是花了两天零碎的时间研究了如何使用nodejs来实现静态页面的接口请求代理。 在实现跨域之前先理清楚我想实现的什么样的功能。

2. 跨域的几种方式

静态网站的里的ajax请求是相对路径,同一套代码要在本地开发环境、测试线环境、大陆正式线、香港正式线部署。所以请求不适合使用绝对路径。

前端跨域

前端跨域的方式有两种

  1. 通过script标签跨域
  2. 通过jsonp跨域

两者的原理都是使用请求静态资源文件的方式,用回调函数的包装把json数据返回前端。从而骗过浏览器的跨域审查。使用这种方法来跨域意味着前端和后端的代码都要根据跨域的要求来重构一番,并且只能发送GET请求,这样的方式肯定是不可行的,因为只有在本地开发时才需要跨域,代码部署到线上服务器后就不需要跨域了。 所以开始研究后端方案跨域。也有两种。

后端跨域

  1. CORS跨域资源共享
  2. 跨域代理服务

CORS (Cross-Origin Resource Sharing)跨域资源共享,它允许浏览器向跨源(协议 + 域名 + 端口)服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。CORS需要浏览器和服务器同时支持,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

  • 参考引用:CORS(跨域资源共享)

使用CORS来实现跨域仍然需要在目标服务器的接口上配置跨域请求参数,所以实现起来要前后端配合还是比较麻烦的。而且仅仅是测试线服务器需要跨域,正式线服务器禁止跨域,这样子修改后,后台代码就会出现不一致。所以此方法也弃用。

跨域代理服务,原理是把前端http请求发送给后台的代理,让代理代为转发请求,从而不需要在浏览器上进行跨域请求。代理获取到响应结果再转发到前端。使用它的好处是目标服务器上的接口代码和前端代码都不需要做任何更改,只需开启本地跨域代理服务即可。

每种跨域方式分析过后,觉得最可行的操作就是使用静态资源代理服务来做前端跨域请求。

3. 使用nodejs跨域代理服务

在nginx和nodejs间选择了后者,于是开始了在本地搭建http服务器和寻找合适的代理跨域中间件。

搭建了本地http服务后,具体怎么操作实现代理跨域其实还是没多大思路的,于是呢就开始百度寻找案例来参考,了解了使用nodejs中间件跨域的大概思路。

先是搭建起http服务器,对访问主机地址的网络请求进行判断,如果是api接口的请求时则使用中间件的代理服务进行转发。让中间件代为向目标服务器发起请求,响应结果再转发至前端。

4. 代码实现

文件结构目录大概如此,ROOT文件夹为网页文件夹

1.创建项目文件夹并npm初始化文件夹

mkdir demo
cd demo
npm init -y
复制代码

2.安装node-http-proxy中间件 npm install http-proxy --save-dev

3.创建启动文件proxy.js

var PORT = 3000;//定义端口号
var tatgetPATH='http://www.a.com/'//目标服务器地址
var http = require('http'); //引入http模块
var url=require('url');  //引入url模块
var fs=require('fs');  //引入文件模块
var mine=require('./fileFormat').types;  //文件格式字典
var path=require('path'); //引入path模块
var httpProxy = require('http-proxy');  //跨域代理中间件var proxy = httpProxy.createProxyServer({target: tatgetPATH,   //接口地址// 下面的设置用于https// ssl: {//     key: fs.readFileSync('server_decrypt.key', 'utf8'),//     cert: fs.readFileSync('server.crt', 'utf8')// },// secure: false
});var server = http.createServer(function (request, response) {var pathname = url.parse(request.url).pathname;//访问根目录时改为指向首页文件if(pathname=='/'){pathname='index.html' }// 指定根目录var realPath = path.join("./ROOT", pathname);var ext = path.extname(realPath);ext = ext ? ext.slice(1) : 'unknown';//判断如果是api接口访问,则通过proxy转发if(pathname.indexOf("./ROOT") > 0){// console.log('发起请求:',pathname)proxy.web(request, response);return;}fs.exists(realPath, function (exists) {if (!exists) {response.writeHead(404, {'Content-Type': 'text/plain'});response.write("This request URL " + pathname + " was not found on this server.");response.end();} else {fs.readFile(realPath, "binary", function (err, file) {if (err) {response.writeHead(500, {'Content-Type': 'text/plain'});response.end(err);} else {var contentType = mine[ext] || "text/plain";response.writeHead(200, {'Content-Type': contentType});response.write(file, "binary");response.end();}});}});
});
server.listen(PORT);//代理服务执行错误的监听
proxy.on('error', function(err, req, res){res.writeHead(500, {'content-type': 'text/plain'});console.log(err);res.end('Something went wrong. And we are reporting a custom error message.');
});
console.log("Server runing at port: " + PORT + "."+tatgetPATH);
复制代码

引入文件格式字典 fileFormat.js

exports.types = {"css": "text/css","gif": "image/gif","html": "text/html","ico": "image/x-icon","jpeg": "image/jpeg","jpg": "image/jpeg","js": "text/javascript","json": "application/json","pdf": "application/pdf","png": "image/png","svg": "image/svg+xml","swf": "application/x-shockwave-flash","tiff": "image/tiff","txt": "text/plain","wav": "audio/x-wav","wma": "audio/x-ms-wma","wmv": "video/x-ms-wmv","xml": "text/xml","woff": "application/x-woff","woff2": "application/x-woff2","tff": "application/x-font-truetype","otf": "application/x-font-opentype","eot": "application/vnd.ms-fontobject"};
复制代码

代码写完后运行proxy.js即可通过跨域代理服务来实现本地调用不同域服务器的接口了。

  • 源码主要参考了下面这篇文章,十分感谢该作者提供的方案。 Node.js配合node-http-proxy解决本地开发ajax跨域问题

5. 总结

跨域的解决方案有很多,具体选择哪一种方案还是根据实际的情况来进行分析。

以前还没学习nodejs的时候,遇到跨域问题能想到的解决方法就是使用ajax的jsonp,需要后端返回的接口加上回调函数,前端再通过通过函数对数据进行接收。改起来十分之麻烦。

前端若是懂得后端的一些知识,便能够使用更多的解决方案来解决问题。web开发中包括了前端和后端,能够熟练使用两端的技能,才能够在web开发中游刃有余。

静态网页使用Node.js跨域代理服务相关推荐

  1. Node.js跨域请求解决方案

    Node.js跨域请求解决方案 一.缘由: 初到公司,老大让去解决之前项目客户提出的一个小问题,对某一模块进行访问验证,之前的项目是PHP做的,对此不了解,因此不打算先学习PHP再去解决问题,考虑到客 ...

  2. node.js跨域问题

    这几天公司同事(前端)写页面的时候一直说拿不到想要的JSON,安卓iOS那边是可以拿到的,但我和都是新手也不知道为什么只知道是js跨域问题,然后我也不懂前端我开始百度, 有人说是谷歌浏览器跨域要设置一 ...

  3. Node.JS跨域请求配置方案

    今天在用node开发的过程中,再次遇到同源策略的问题: 在客户端调用服务端获取数据时,Chrome 浏览器中报错如下: Access to XMLHttpRequest at 'http://loca ...

  4. Vue.js跨域请求配置、Node.js设置允许跨域

    Vue跨域配置 在Vue项目目录中打开config/index.js,在proxyTable中添写如下代码: // 跨域处理proxyTable: {'/api': { // 匹配所有以 '/api' ...

  5. js跨域请求方式 ---- JSONP原理解析

    这篇文章主要介绍了js跨域请求的5中解决方式的相关资料,需要的朋友可以参考下 跨域请求数据解决方案主要有如下解决方法: 1 2 3 4 5 JSONP方式 表单POST方式 服务器代理 Html5的X ...

  6. 新版vue-cli模板下本地开发环境使用node服务器跨域

    背景 我们都知道浏览器有一个既核心也最基本的安全功能,即同源策略.同源分别是:协议,域名,端口.如果浏览器访问服务器不同源的话,就会访问不到数据.那开发中常常访问的服务器不同源,那么可以借助一个服务器 ...

  7. jsonp-反向代理-CORS解决JS跨域问题的个人总结

    jsonp-反向代理-CORS解决JS跨域问题的个人总结 网上说了很多很多,但是看完之后还是很混乱,所以我自己重新总结一下. 解决 js 跨域问题一共有8种方法, jsonp(只支持 get) 反向代 ...

  8. vue读取服务器文件跨域,新版vue-cli模板下本地开发环境使用node服务器跨域的方法...

    背景 我们都知道浏览器有一个既核心也最基本的安全功能,即同源策略.同源分别是:协议,域名,端口.如果浏览器访问服务器不同源的话,就会访问不到数据.那开发中常常访问的服务器不同源,那么可以借助一个服务器 ...

  9. js跨域访问,No 'Access-Control-Allow-Origin' header is present on the requested resource

    js跨域访问提示错误:XMLHttpRequest cannot load http://...... No 'Access-Control-Allow-Origin' header is prese ...

最新文章

  1. 动态产生一个TextBox,并使输入的文本靠右对齐
  2. python中延时函数_python中实现延时回调普通函数示例代码
  3. 游戏编程性能优化--------------------------------------------------------------------------------------...
  4. 基于 HanLP 的 ES 中文分词插件
  5. STM32F103mini基础知识归纳
  6. [Python3] 初识py, 一个简单练手的小玩意. 快递查询
  7. python ssologin_django-sso单点登陆的实现
  8. 农行总行携手趣链科技上线区块链涉农电商融资产品
  9. 【考研高数 自用】高数第一章基础阶段思维导图
  10. 几个好用的资源下载网址
  11. 系统发育树的构建方法介绍及数据问题等(古生物形态学数据)
  12. 爬取https://sc.chinaz.com/tupian/的图片
  13. Instagram第三方接入
  14. 数学建模——计算机工具的使用(1)——SPSS操作以及在统计分析中的应用
  15. AD软件关于覆铜的高级规则设置
  16. QCustomPlot之盒须图(十六)
  17. 《微信小程序案例5》仿小米Lite小程序分类板块-两个纵向滚动区域独立互不影响
  18. yeelight智能设备+HomeKit+智汀家庭云,从零开始打造全屋智能
  19. 被字句15个_二年级语文上册把字句被字句练习
  20. Java面试之语言基础

热门文章

  1. JDK1.5-1.7 比较二
  2. FMDB:中的用法介绍
  3. zabbix在windows服务器下监控
  4. 去邵程程博客,得到很有喜感图片一张
  5. dataframe 转rdd java,在pyspark中将RDD转换为Dataframe
  6. 数据结构 结构的声明 一个结构作为另一个结构的成员 单向链表的实现 双向链表的实现
  7. 关于kali相关的参考文章
  8. Django中过滤的实现
  9. .NET Core微服务系列基础文章索引(目录导航Final版)
  10. noip模拟题 ----飞