摘要:注意,该请求的查询字符串有一个参数,用来指定回调函数的名字,这对于是必需的。服务器收到这个请求以后,会将数据放在回调函数的参数位置返回。
有关同源策略详细介绍,请看这里JSONP
JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务器改造非常小。
它的基本思想是,网页通过添加一个元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
首先,网页动态插入元素,由它向跨源网址发出请求。
例子:
客服端
function addScriptTag(src) { var script = document.createElement("script"); script.setAttribute("type","text/javascript"); script.src = src; document.body.appendChild(script); } window.onload = function () { addScriptTag("http://localhost:3000/test?callback=foo"); } function foo(data) { console.log("Your public IP address is: " + data.ip); };
上面代码通过动态添加元素,向服务器http://localhost:3000发出请求。注意,该请求的查询字符串有一个callback参数,用来指定回调函数的名字,这对于JSONP是必需的。
服务器收到这个请求以后,会将数据放在回调函数的参数位置返回。
JavaScript服务端
var express = require("express"); var app = express(); app.get("/test", function (req, res) { var cbFunction = req.query.callback res.send(`${cbFunction}({"ip":"110.110.110.110"})`); //或者不用那么麻烦直接通过express提供的API /** * res.jsonp({ip:"110.110.110.110"}); */ }); var server = app.listen(3000, function () { var host = server.address().address; var port = server.address().port; console.log("Example app listening at http://%s:%s", host, port); });
上面代码通过express做的简单后台,当请求接口时,后端拿到callback参数然后将其与要返回的数据组合成字符串的形式返回给客户端。
由于元素请求的脚本,直接作为代码运行。这时,只要浏览器定义了foo函数,该函数就会立即调用。作为参数的JSON数据被视为JavaScript对象,而不是字符串,因此避免了使用JSON.parse的步骤。
CORS有两种请求 :简单请求(simple request)和非简单请求(not-so-simple request)只要同时满足以下两大条件,就属于简单请求。
请求方法是以下三种方法之一:
HEAD
GET
POST
HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
凡是不同时满足上面两个条件,就属于非简单请求。
浏览器对这两种请求的处理,是不一样的。
客户端
var xhr = new XMLHttpRequest() xhr.open("post","http://localhost:3000/test",true) xhr.onload = function(e){ if(e.currentTarget.status==200){ alert(e.currentTarget.responseText) } } xhr.send()
RequestHeaders请求头信息
Accept:/*/ Accept-Encoding:gzip, deflate, br Accept-Language:zh-CN,zh;q=0.8 Connection:keep-alive Content-Length:0 Host:localhost:3000 Origin:http://localhost:8020 Referer:http://localhost:8020/ User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
JavaScript服务端
app.post("/test", function (req, res) { res.set("Access-Control-Allow-Origin","http://localhost:8020") res.send({ name:"tom" }) });
ResponseHeaders
Access-Control-Allow-Origin:http://localhost:8020 Connection:keep-alive Content-Length:14 Content-Type:application/json; charset=utf-8 Date:Mon, 09 Apr 2018 02:09:05 GMT ETag:W/"e-v50e5W1R/vD6VVQyxqDA0eSWedA" X-Powered-By:Express非简单请求 预检请求
客户端
var xhr = new XMLHttpRequest() xhr.open("put","http://localhost:3000/test",true) xhr.setRequestHeader("X-Custom-Header", "value"); xhr.onload = function(e){ if(e.currentTarget.status==200){ alert(e.currentTarget.responseText) } } xhr.send()
当发送上面的http请求时浏览器会先发送一个options类型的http的预检请求
RequestHeaders请求头信息
Accept:*/* Accept-Encoding:gzip, deflate, br Accept-Language:zh-CN,zh;q=0.8 Access-Control-Request-Headers:x-custom-header Access-Control-Request-Method:PUT Connection:keep-alive Host:localhost:3000 Origin:http://localhost:8020 Referer:http://localhost:8020/ User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
JavaScript服务端
//options类型用于CORS非简单请求的预检请求 app.options("/test",function(req,res){ res.set("Access-Control-Allow-Origin","http://localhost:8020") //必须设置 res.set("Access-Control-Allow-Methods","PUT") //必须设置 res.set("Access-Control-Allow-Headers","X-Custom-Header") //如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。 res.send({status:200,msg:"预检成功!"}) })
ResponseHeaders
Access-Control-Allow-Headers:X-Custom-Header Access-Control-Allow-Methods:PUT Access-Control-Allow-Origin:http://localhost:8020 Connection:keep-alive Content-Length:38 Content-Type:application/json; charset=utf-8 Date:Mon, 09 Apr 2018 04:08:40 GMT ETag:W/"26-+1THtR73k4ca8avMcdsJULlJZUs" X-Powered-By:Express
关于客户端和服务端字段相应说明可以在这里查看正常请求和回应
一旦服务器通过了"预检"请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样,会有一个Origin头信息字段。服务器的回应,也都会有一个Access-Control-Allow-Origin头信息字段。
客户端
RequestHeaders请求头信息
Accept:*/* Accept-Encoding:gzip, deflate, br Accept-Language:zh-CN,zh;q=0.8 Connection:keep-alive Content-Length:0 Host:localhost:3000 Origin:http://localhost:8020 Referer:http://localhost:8020/ User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36 X-Custom-Header:value
上面头信息的Origin字段是浏览器自动添加的。
JavaScript服务端
app.put("/test", function (req, res) { res.set("Access-Control-Allow-Origin","http://localhost:8020") res.send({ name:"tom" }) });
ResponseHeaders
Access-Control-Allow-Origin:http://localhost:8020 Connection:keep-alive Content-Length:14 Content-Type:application/json; charset=utf-8 Date:Mon, 09 Apr 2018 04:08:40 GMT ETag:W/"e-v50e5W1R/vD6VVQyxqDA0eSWedA" X-Powered-By:Express
上面头信息中,Access-Control-Allow-Origin字段是每次回应都必定包含的。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/94208.html
摘要:关于,强烈推荐阅读跨域资源共享详解阮一峰另外,这里也整理了一个实现原理图简化版如何判断是否是简单请求浏览器将请求分成两类简单请求和非简单请求。 前言 从刚接触前端开发起,跨域这个词就一直以很高的频率在身边重复出现,一直到现在,已经调试过N个跨域相关的问题了,16年时也整理过一篇相关文章,但是感觉还是差了点什么,于是现在重新梳理了一下。 个人见识有限,如有差错,请多多见谅,欢迎提出iss...
摘要:本地也可以轻松模拟跨域请求,以及解决跨域请求的方式轻松实现本地服务器跨域请求请求接口,其实它们都在相同的本地服务器目录下以访问页面,可是这个页面调用的接口地址是与域名不同,也即跨域解决跨域请求服务器端设置这样就能轻松实现跨域请求 本地也可以轻松模拟跨域请求,以及解决跨域请求的方式 1、轻松实现本地服务器跨域请求 web.html请求接口json.json,其实它们都在相同的本地服务器目...
摘要:前言由于自己平时只做做,并没有遇到太多跨域问题,今天通过几个样例模拟实现了几种跨域方式。 前言 由于自己平时只做做demo,并没有遇到太多跨域问题,今天通过几个样例模拟实现了几种跨域方式。原文地址 传送门 本文所有样例静态服务器基于nodejs实现,代码亲测可用。测试步骤如下: 1.为了实现跨域访问的效果,需要下载http-server 作为一个服务器 npm install http...
摘要:二跨域解决方案原理利用标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的数据。使用反向代理实现跨域,是最简单的跨域方式。 前言 前后端数据交互经常会碰到请求跨域,什么是跨域,以及有哪几种跨域方式,这是本文要探讨的内容。 本文完整的源代码请猛戳github博客,纸上得来终觉浅,建议动手敲敲代码 一、什么是跨域? 1.什么是同源策略及其限制内容? 同源策略是一种约定,它是浏览器最核心...
摘要:二跨域解决方案原理利用标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的数据。使用反向代理实现跨域,是最简单的跨域方式。 前言 前后端数据交互经常会碰到请求跨域,什么是跨域,以及有哪几种跨域方式,这是本文要探讨的内容。 本文完整的源代码请猛戳github博客,纸上得来终觉浅,建议动手敲敲代码 一、什么是跨域? 1.什么是同源策略及其限制内容? 同源策略是一种约定,它是浏览器最核心...
阅读 2928·2021-11-04 16:06
阅读 767·2021-09-30 09:56
阅读 1830·2021-09-22 10:02
阅读 2612·2019-08-29 13:43
阅读 2198·2019-08-29 13:42
阅读 2288·2019-08-29 12:21
阅读 1037·2019-08-29 11:29
阅读 1375·2019-08-26 13:51