设为首页 收藏本站
云服务器等爆品抢先购,低至4.2元/月
查看: 1150|回复: 0

[经验分享] Nodejs(七)-跨域访问

[复制链接]

尚未签到

发表于 2017-2-21 11:50:18 | 显示全部楼层 |阅读模式
转载自: http://xfhnever.com/blog/2014/08/14/nodejs-crossdomainaccess/
 
今天在使用ajax(http://localhost:8080%EF%BC%89%E8%B0%83%E7%94%A8nodejs%E5%86%99%E7%9A%84restfulAPI(http://localhost:3000%EF%BC%89%E6%97%B6%EF%BC%8C%E6%8A%A5%E4%BA%86%E5%A6%82%E4%B8%8B%E4%B8%80%E4%B8%AA%E9%94%99%E8%AF%AF%EF%BC%9A

XMLHttpRequest cannot load http://localhost:3000/mock/items.
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8080' is therefore not allowed access.

晚上说不能跨域访问,完全不懂这个概念啊,所以简单介绍一下。

解决方案

首先给大家介绍一下这个问题的解决方案,我是在node代码中设置跨域访问。

var app = express();  
//设置跨域<strong>访问</strong>  
app.all('*', function(req, res, next) {  
res.header("Access-Control-Allow-Origin", "*");  
res.header("Access-Control-Allow-Headers", "X-Requested-With");  
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");  
res.header("X-Powered-By",' 3.2.1')  
res.header("Content-Type", "application/json;charset=utf-8");  
next();  
});

把Access-Control-Allow-Origin设置为‘*’,表示任意origin可以访问该API. 在实际应用中这样是不安全的,需要制定具体的origin。
当然也可以只对某些url设置跨域访问:

router.get('/', function(req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.send('respond with a resource');
});

何为跨域

域(Domain)是Windows网络中独立运行的单位,域之间相互访问则需要建立信任关系(即Trust Relation)。信任关系是连接在域与域之间的桥梁。当一个域与其他域建立了信任关系后,2个域之间不但可以按需要相互进行管理,还可以跨网分配文件和打印机等设备资源,使不同的域之间实现网络资源的共享与管理。
跨域请求,顾名思义,就是一个站点中的资源去访问另外一个不同域名站点上的资源。这种情况很常见,比如说通过style标签加载外部样式表文件、通过 img 标签加载外部图片、通过 script 标签加载外部脚本文件、通过 Web font 加载字体文件等等。默认情况下,脚本访问文档属性等数据采用的是同源策略(Same origin policy)。
同源策略:如果两个页面的协议、域名和端口是完全相同的(IE的同源策略不包含端口),那么它们就是同源的。同源策略是为了防止从一个地址加载的文档或脚本访问或者设置从另外一个地址加载的文档的属性。如果两个页面的主域名相同,则还可以通过设置document.domain 属性将它们认为是同源的。
出于安全性考虑,浏览器将不允许跨域页面间的JS相互操作,如:主页面和跨域IFrame之间的JS操作,也不允许XMLHttprequest请求跨域内容。
在浏览器中不能直接来跨域访问,而在服务器端没有跨域安全限制。

其他解决方法



  • 主域名相同的跨域情形
    设置document.domain属性。如果想做到数据的交互,那么www.aa.com和book.aa.com必须由你来开发才可以。可以将book.aa.com用iframe添加到 www.aa.com的某个页面下,在www.aa.com和iframe里面都加上document.domain = “aa.com”,这样就可以统一域了,可以实现跨域访问。就和平时同一个域中镶嵌iframe一样,直接调用里面的JS就可以了。


  • HASH传值
    当两个域不同时,如果想相互调用,那么同样需要两个域都是由你来开发才可以。用iframe可以实现数据的互相调用。解决方案就是用window.location对象的hash属性。hash属性就是http://domian/web/a.htm#dshakjdhsjka 里面的#dshakjdhsjka。利用JS改变hash值网页不会刷新,可以这样实现通过JS访问hash值来做到通信。不过除了IE之外其他大部分浏览器只要改变hash就会记录历史,你在前进和后退时就需要处理,非常麻烦。不过再做简单的处理时还是可以用的。大体的过程是页面a和页面b在不同域下,b通过iframe添加到a里,a通过JS修改iframe的hash值,b里面做一个监听(因为JS只能修改hash,数据是否改变只能由b自己来判断),检测到b的hash值被修改了,得到修改的值,经过处理返回a需要的值,再来修改a的hash值(这个地方要注意,如果a 本身是那种查询页面的话比如http://domian/web/a.aspx?id=3,%E5%9C%A8b%E4%B8%AD%E7%9B%B4%E6%8E%A5parent.window.location%E6%98%AF%E6%97%A0%E6%B3%95%E5%8F%96%E5%BE%97%E6%95%B0%E6%8D%AE%E7%9A%84%EF%BC%8C%E5%90%8C%E6%A0%B7%E6%8A%A5%E6%B2%A1%E6%9C%89%E6%9D%83%E9%99%90%E7%9A%84%E9%94%99%E8%AF%AF%EF%BC%8C%E9%9C%80%E8%A6%81a%E6%8A%8A%E8%BF%99%E4%B8%AA%E4%BC%A0%E8%BF%87%E6%9D%A5%EF%BC%8C%E6%89%80%E4%BB%A5%E4%B9%9F%E6%AF%94%E8%BE%83%E9%BA%BB%E7%83%A6%EF%BC%89%EF%BC%8C%E5%90%8C%E6%A0%B7a%E9%87%8C%E9%9D%A2%E4%B9%9F%E8%A6%81%E5%81%9A%E7%9B%91%E5%90%AC%EF%BC%8C%E5%A6%82%E6%9E%9Chash%E5%8F%98%E5%8C%96%E7%9A%84%E8%AF%9D%E5%B0%B1%E5%8F%96%E5%BE%97%E8%BF%94%E5%9B%9E%E7%9A%84%E6%95%B0%E6%8D%AE%EF%BC%8C%E5%86%8D%E5%81%9A%E7%9B%B8%E5%BA%94%E7%9A%84%E5%A4%84%E7%90%86%E3%80%82


  • JS脚本植入
    通过页面动态加载<script>标签实现,该标签的SRC属性设置为跨域请求的URL地址,返回的内容为method(…)形式,其中method为页面内的JS回调函数,通过执行该函数来实现改变。


  • JQuery实现

    function jsonpajax_1() {
    $.ajax({
    url: "http://192.168.1.105:8123/Handler.ashx?callback=?",
    type: "get",
    dataType: "jsonp",
    jsonp: "callback",
    success: function(data) {
    var tt = '';
    $.each(data, function(k, v) {
    tt += k + ":" + v + "<br/>";
    });
    $("#divmessage").html(tt);
    }
    });
    }

此时,跨域的Web1中的ashx文件数据提供要改一下:

    string callback = context.Request.Params["callback"];
context.Response.Write(callback+"("+strJson+")");

jsonp的最基本的原理是:动态添加一个<script>标签,而script标签的src属性是没有跨域的限制的。这样说来,这种跨域方式其实与ajax XmlHttpRequest协议无关了.
如果设为dataType: ‘jsonp’, 这个$.ajax方法就和ajax XmlHttpRequest没什么关系了,取而代之的则是JSONP协议.
JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问
JSONP即JSON with Padding。由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。如果要进行跨域请求,
我们可以通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递javascript对象。
这种跨域的通讯方式称为JSONP。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-345241-1-1.html 上篇帖子: Nodejs(七)-跨域访问 下篇帖子: Nodejs(七)-跨域访问
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表