问题:跨域有哪些方法?jsonp的原理是什么?

jsonp:

先说jsonp,jsonp的主要原理是利用script标签的src可以跨域请求,据说有src属性的都可以跨域请求,但script标签返回的会直接执行,所以都是用script请求。jsonp=json+padding,padding是指服务器返回数据时把数据用padding(函数)包裹了起来。也就是说,一般情况下浏览器向服务器发送请求得到的都是数据(文本,XML,JSON),但是当采用JSONP技术时候,浏览器向跨域服务器发送请求,得到的是回调函数包住的JSON。此处JSON作为参数传入回调函数,然后再返回给浏览器。

这里写一个例子:其中后台用的nodejs

前端代码:index.html

<html>
<head></head>
<body>
<div id="myDiv"></div>
</body>
<script type="text/javascript">
function jsonpcallback(data){
console.log(data.text)
}
var s = document.createElement('script');
s.src="http://localhost:3000?callback=jsonpcallback";
document.body.appendChild(s);
</script>
</html>

后台代码:server.js

var http = require('http')
var url = require('url') http.createServer(function(req,res){
var param = url.parse(req.url, true).query
var callback = param.callback
var data = {
text: "hello world"
}
var resStr = callback+"("+JSON.stringify(data)+")"
res.write(resStr)
res.end()
}).listen(3000)

上面的例子中,index.html中定义了一个jsonpcallback函数,并且把这个函数名通作为callback字段的值以get的请求(src的请求只能是get)发送给服务端。服务端接收到之后通过callback字段拿到回调函数名,然后用这个函数名包裹要返回的数据,形成一个字符串,发给前端

例子在node环境下运行:node server.js,然后再运行index.html就可以看到前端跨域请求的结果。例子中由于index.html是本地的,所以跟服务器不同源,普通的请求会被拒绝。

服务端写的时候要注意,返回的是一个很像函数调用的字符串,它不并不是后台对callback函数的调用,所以要把返回的对象用JSON.stringify转化一下,再加上字符串的两个括号

CORS:

jsonp说完之后,再说一个常用的跨域方法CORS。主要参考阮一峰大神的资料:http://www.ruanyifeng.com/blog/2016/04/cors.html

CORS分简单请求和非简单请求,同时满足下面两个条件的就是简单请求,否则就是非简单请求

简单请求:请求头通过Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。

我在实际测试时先不使用关于cookie的一些可选字段,就简单的在前端设置Origin在后端设置Access-Control-Allow-Origin这种必须的字段来测试。

发现前端的ajax设置Origin字段会报错-》Refused to set unsafe header "Origin"

虽然不影响请求的发送,但设置的Origin字段是无效的,不管我设置什么或者不设置这个字段时查看Origin字段时它的值都是null,网上查了之后在stackoverflow上有人说那个Origin字段本来就应该是浏览器来设置的,自己设置不安全。

猜想只要浏览器发现请求的目标不是同源的,就会自己给报文加Origin字段。所以只要在后端设置Access-Control-Allow-Origin字段为*(表示接受任意Origin的请求)就可以了。

前端代码:简单的ajax即可

服务端代码:server.js

var http = require('http')

http.createServer(function(req,res){
res.writeHead(200, {
'Access-Control-Allow-Origin' : '*'
});
res.write("hello world!")
res.end()
}).listen(3000)

非简单请求:除去可选字段,在非简单请求中服务端还要指定Access-Control-Request-Method来表示自己接受的请求的方法,把之前的ajax中的方法从get改为put

前端代码:index.html

<html>
<head></head>
<body>
<div id="myDiv"></div>
</body>
<script type="text/javascript">
var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP")
xmlhttp.open("PUT","http://localhost:3000/",true)
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.send()
</script>
</html>

如果后台没有在Access-Control-Request-Method中添加put方法就会报错-》Failed to load http://localhost:3000/: Method PUT is not allowed by Access-Control-Allow-Methods in preflight response.

后端代码:server.js

var http = require('http')
var url = require('url') http.createServer(function(req,res){
res.writeHead(200, {
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods' : 'GET, POST, PUT'
});
res.write("hello world!")
res.end()
}).listen(3000)

添加了Access-Control-Request-Method:“PUT”后请求成功。

非简单方法浏览器会先发起一个method为OPTION的“预检”来跟服务器验证自己的请求是不是被允许,如果服务器回的头中没有请求的方法或者参数,那么浏览器就知道不允许,将不发送ajax请求。如果有,浏览器才会再发送那个ajax请求。

“预检”请求:

CORS和jsonp的区别主要在于:jsonp只支持get请求,而CORS支持所有类型的请求,只不过CORS要求至少IE10,jsonp兼容以前的版本。

面试整理(2)跨域:jsonp与CORS的更多相关文章

  1. 小结ajax中的同源和跨域 jsonp和cors

    网上的同源和跨域一般都比较复杂,最近也稍微总结了一下: 所谓同源,是浏览器的一种安全机制,作用在于保护网页数据的安全,不同源的网页之间不允许cookie dom ajax等行为 同源的条件:1.协议相 ...

  2. AJAX_违反了同源策略_就是"跨域"——jsonp 和 cors

    https 协议    默认端口号 443 http 协议    默认端口号 80 同源策略 由网景公司提出的——浏览器 的 为了浏览器安全而生 同源策略: 协议.域名.端口号    必须完全一致 违 ...

  3. 跨域-jsonp、cors、iframe、document.domain、postMessage()

    同源策略 概念:同源: 协议.域名.端口号 完全相同 同源策略是浏览器的一种安全策略:且浏览器不会将违反同源策略的响应信息返回 http://127.0.0.1:3000/index.html     ...

  4. 跨域 jsonp 和 CORS 资料

    http://mp.weixin.qq.com/s/iAShnqvsOyV-Xd0Ft7Nl2Q HTML5安全:CORS(跨域资源共享)简介...ie67不要想了... http://www.cnb ...

  5. AJAX学习笔记2:XHR实现跨域资源共享(CORS)以及和JSONP的对比----转载

    1 前言: 首先对参考文章作者表示感谢,你们的经验总结给我们这些新手提供了太多资源.本文致力于解决AJAX的CORS问题,我在逻辑上进行了梳理:首先,系统的总结了CORS问题的起源-同源策略:其次,介 ...

  6. ajax跨域请求解决方案 CORS和JSONP

    什么是跨域: 只要协议.域名.端口有任何一个不同,都会被当成不同的域.而由于浏览器的同源策略(同源策略:域名.协议.端口均相同),浏览器之间要隔离不同域的内容,禁止互相操作,不能执行其他网站的js.所 ...

  7. 什么是同源策略,什么是跨域,如何跨域,Jsonp/CORS跨域

    同源策略 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响. 可以说Web是构建在同源策略基础之上 ...

  8. js实现跨域(jsonp, iframe+window.name, iframe+window.domain, iframe+window.postMessage)

    一.浏览器同源策略 首先我们需要了解一下浏览器的同源策略,关于同源策略可以仔细看看知乎上的一个解释.传送门 总之:同协议,domain(或ip),同端口视为同一个域,一个域内的脚本仅仅具有本域内的权限 ...

  9. 使用jQuery-AJAX–读取获得跨域JSONP数据的示例

    在项目开发中,如果在同一个域名下就不存在跨域情况,使用$.getJSON()即可实现.但是需要跨域请求其他域名下面的Json数据就需要JSONP的方式去请求,跨域写法和getJSON有差异.如下:   ...

  10. 【fetch跨域请求】cors

    当使用fetch 发起跨域请求时,CORS(跨域资源共享Cross-origin resource sharing) 请求fetch const body = {name:"Good boy ...

随机推荐

  1. css新增UI方案

    一.文本新增样式 opacity 不透明度 h1{ margin: 100px auto; opacity: 0.5; } </style> </head> <body& ...

  2. IT行业大学生就业分析报告感想

    现如今的高校毕业生每年都在增长,就业压力只增不减,人才市场挤满了人 学生们普遍的表现出就业难的情况,并且适合自己的工作也难找 从报告中也容易看出IT行业很吸引人,也是人数最多的,因此机会也就变少了 在 ...

  3. 201621123037 《Java程序设计》第10周学习总结

    作业10-异常 标签(空格分隔): Java 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1. 常用异常 结合题集题目7 ...

  4. php中ob缓存机制

    1.ob缓存运行方式 2.注意:在程序中如果开启ob_start(),所有的echo输出都会保存到ob缓存中,可以使用ob系列函数进行操作,如果没有,默认情况下,在程序执行结束,会把缓存中的数据发送给 ...

  5. 组件式开发框架 craftyjs

    想要少写代码,请用组件式开发吧.传统的oop,一直做着重复的事性. 先理解下概念 Entity            实体        An entity is just an ID Compone ...

  6. Js 中实现重定向的几种方式

    之所以要总结这个,是因为在项目中使用了 AJAX,当请求成功时需要重定向到另一个页面. 1 . <script type="text/javascript"> wind ...

  7. java map的 keyset()方法

  8. P2610 [ZJOI2012]旅游

    题目描述 到了难得的暑假,为了庆祝小白在数学考试中取得的优异成绩,小蓝决定带小白出去旅游~~ 经过一番抉择,两人决定将T国作为他们的目的地.T国的国土可以用一个凸N边形来表示,N个顶点表示N个入境/出 ...

  9. Django安装及简介

    一. Django简介 Python下有许多款不同的 Web 框架.Django是重量级选手中最有代表性的一位.许多成功的网站和APP都基于Django. Django是一个开放源代码的Web应用框架 ...

  10. Intel WIDI (Wireless Display) 相关技术知识分析

    一. WIFI 1.如何查找WIFI设备 非p2p设备 Beacons 包(同步,SSID) 速率 1M/s 2.4G HZ 13个信道,1,6,11三个信道不重叠 2.P2P 认证 客户端在每个通道 ...