前后端交互

您所在的位置:网站首页 axios跨域处理 前后端交互

前后端交互

2024-03-15 21:53| 来源: 网络整理| 查看: 265

URL地址

URL(Uniform Resource Locator)统一资源定位符

作用:标识互联网上每个资源的唯一存放位置

url的结构.png

表单提交

方式:HTML中的标签,就是用于采集用户输入的信息,并通过标签的提交操作,把采集到的信息提交到服务器端进行处理

表单的属性 action 指定表单的提交地址,默认值为当前页面的 URL 地址 当提交表单后,页面会立即跳转到 action 属性指定的 URL 地址 method 指定表单的提交方式,默认为get get/post

​ get:

数据会拼接在 url 地址的后面?name=admin&pwd=123456

地址栏有长度限制,因此 get 方式提交数据大小不会超过 4k

GET 用于信息获取

post:

数据不会在 url 中显示,相比 get 方式,post 更安全

提交的数据没有大小限制

POST 表示可能修改服务器上的资源的请求

form表单的注意点 input 的数据想要提交到后台,必须指定name属性,后端通过name属性获取值 想要提交表单,不能使用 input:button 必须使用 input:submit HTTP协议

HTTP协议(Hypertext transfer protocol)超文本传输协议

作用:HTTP协议规定了客户端与服务器之间进行的网页内容传输时, 所必须遵守的传输格式

get 请求的请求报文详解 //--------------------------请求行-------------------------------- GET /day02/01.php?username=lw&password=123456 HTTP/1.1 // GET 请求方式 // /day02/01.php?username=lw&password=123456 请求路径+参数(注意点) // HTTP/1.1 HTTP的版本号 //--------------------------请求头-------------------------------- // Host:主机地址 Host: www.study.com // HTTP1.1版本默认开启,建立过连接后,TCP连接不会断开,下次连接可以继续使用 Connection: keep-alive //chrome浏览器自己增加的 Upgrade-Insecure-Requests: 1 //浏览器的代理字符串(版本信息) User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36 //浏览器端可以接受的类型。 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,`*/*`;q=0.8 //从哪个页面发出的请求 Referer: http://www.study.com/day02/01-login.html //检查浏览器支持的压缩方式 Accept-Encoding: gzip, deflate, sdch //浏览器支持的语言,优先中文。 Accept-Language: zh-CN,zh;q=0.8,en;q=0.6 //----------------------------请求体------------------------------------- // get请求没有请求体,但是参数会拼接到请求行中 POST 请求的请求报文 //-----------------------请求行--------------------------------------------- POST /day02/01.php HTTP/1.1 //-----------------------请求头-------------------------------------------- Host: www.study.com Connection: keep-alive // ★ 传递的参数的长度。 Content-Length: 29 Cache-Control: max-age=0 Origin: http://www.study.com Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36 // ★ 内容类型:表单数据,如果是post请求,必须指定这个属性。 Content-Type: application/x-www-form-urlencoded Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,`*/*`;q=0.8 Referer: http://www.study.com/day02/01-login.html Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.8,en;q=0.6 //------------------------请求体------------------------------------------ username=lw&password=123456

GET 请求与 POST 请求的对比

GET 请求没有请求体,因为 GET 请求的参数拼接到地址栏中了 POST 请求有请求体,就是传递的参数 POST 请求需要指定 content-type 属性。 响应与响应报文 //---------------------状态行(响应行)------------------------------- HTTP/1.1 200 OK //HTTP/1.1 HTTP版本 //200 响应的状态 //200表示成功 //404表示找不到资源 //500表示服务端错误 //----------------------响应头----------------------------------------------- Date: Thu, 22 Jun 2017 16:51:22 GMT Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.4.45 X-Powered-By: PHP/5.4.45 Content-Length: 18 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive //内容类型,告诉浏览器该如何解析响应结果 Content-Type: text/html;8 //-----------------------响应体------------------------------------------------ 用户登录成功

可以直接使用谷歌浏览器来查看请求报文和响应报文。谷歌浏览器会对报文进行一定的格式化,看起来虽然不是原生的报文,但是使用起来更加的方便简洁。

Ajax

ajax(Asynchronous Javascript And XML)异步JavaScript和XML

作用:在 HTTP 协议的基础上以异步的方式与服务器进行通信

传统的Ajax与JQuery ajax

传统 Ajax 指的是 XMLHttpRequest(XHR), 最早出现的发送后端请求技术,隶属于原始js中,核心使用XMLHttpRequest对象,多个请求之间如果有先后关系的话,就会出现回调地狱 (在异步js里,回调函数写的太多,回调套回调,代码繁琐)

JQuery ajax 是对原生XHR的封装,除此以外还增添了对JSONP的支持

ajax和form表单的对比 都能够发送http请求,ajax发送的是异步的http请求,表单发送的是同步的http请求 使用表单发送请求,页面一定会发生跳转;ajax允许你在操作页面的同时异步的发送请求,页面可以不跳转 传统的Ajax(XMLHttpRequest)

XMLHttpRequest(简称 xhr)是浏览器提供的 Javascript 对象,用于与服务器通信(交换数据)。

作用:实现对网页的部分更新,而不是刷新整个页面。这个请求是异步,即在往服务器发送请求时,并不会阻碍程序的运行,浏览器会继续渲染后续的结构。

最简单的用法 let xhr = new XMLHttpRequest()

发送 get 请求

使用XMLHttpRequest发送get请求的步骤:

创建 xhr 对象

let xhr = new XMLHttpRequest()

请求行 - 调用 xhr.open() 函数

xhr.open( ‘ get ’ , ' url地址 ?参数拼接的字符串 ' )

请求体 - 调用 xhr.send() 函数

xhr.send(null)

// 点击按钮准备 发送请求 let btn = document.querySelector('button') btn.onclick = function () { ... } //1. 创建一个ajax对象, xhr 就是ajax实例, 可以发送请求 var xhr = new XMLHttpRequest(); // 2. 设置请求的三部分 // 2.1 设置请求行 // 参数1 :请求方式 // 参数2 : 请求url地址 xhr.open('get', 'http://111.222.3.444:9999/v1/get?name=admin&pwd=123456') // 2.2 需要设置请求头 // get请求的请求头浏览器默认会添加, 此处不用设置请起头了 // 2.3 设置请求体 get请求没有请求体, 因为请求体就是放参数的, 参数已经拼在 url上了 // 注意:必须调用send才会发送请求,get请求,参数为null // 参数:请求体 xhr.send() 发送 post 请求

步骤:

创建 xhr 对象

let xhr = new XMLHttpRequest()

请求行 - 调用 xhr.open() 函数

xhr.open( ‘ post ’ , ' url地址 ' )

请求头 - 设置 Content-Type 属性(固定写法)

xhr.setRequestHeader( ' content-type ' , ' application/x-www-form-urlencoded ' )

请求体 - 调用 xhr.send() 函数,同时指定要发送的数据

xhr.send( 参数拼接的字符串 )

// 1. 创建 xhr let xhr = new XMLHttpRequest() // 2. 请求 // 2.1 请求行 xhr.open('post','http://111.222.3.444:9999/v1/post') // 2.2 请求头 // Content-Type: application/x-www-form-urlencoded xhr.setRequestHeader('content-type','application/x-www-form-urlencoded') // 2.3 请求体 xhr.send('name=admin&pwd=123456') post 请求, 参数列表不能拼接到 url 后面 post 必须设置请求头中的 content-type 为 application/x-www-form-urlencoded post 请求需要将参数放到send中 获取响应 // 结构 提交 // 点击按钮准备 let btn = document.querySelector('button') btn.onclick = function () { ... } // 1. 收集数据 let name = document.querySelector('.name').value let pwd = document.querySelector('.pwd').value // 2. 发送ajax 请求 let xhr = new XMLHttpRequest() xhr.open('get', `http://111.222.3.444:9999/v1/get?name=${name}&pwd=${pwd}`) xhr.send() // 3. 获取响应 xhr.onload = function () { // console.log(xhr); // console.log(xhr.status); // console.log(xhr.responseText); if (xhr.status === 200) { alert(xhr.responseText) } else { alert('请求失败') } } jQuery 中的 ajax 方法

jQuery 中发起 Ajax 请求最常用的三个方法如下:

jq中的Ajax.png

$.ajax的参数列表 参数名称描述取值示例url后台地址url:"02.php"type请求方式get/posttype:"get"dataType服务器返回的数据格式json/xml/text,如果不指定,会自动根据 content-type 进行判定dataType:"json"data发送的请求数据对象、字符串data:{name:"zs", age:18}beforeSend调用前的回调函数,在 beforeSend 中 return false,会阻止 ajax 的发送function(){}beforeSend:function(){ }success成功的回调函数function (data) {}success:function (data) {}error失败的回调函数function (error) {}error:function(data) {}complete完成后的回调函数function () {}complete:function () {}

示例:

$.ajax({ type: "get", //请求类型 url: "02.php", //请求地址 data: { name: "zs", age: 18 }, //请求数据 beforeSend: function() { //alert("发送ajax前调用"); }, success: function(data) { //alert("请求成功时调用"); console.log(data); }, error: function(error) { //alert("请求失败时调用"); console.log(error); }, complete: function() { //alert("请求完成时调用, 不论失败还是成功都会执行"); }, });

$.ajax() 函数的基本语法:

$.ajax({ type: '', // 请求的方式,例如 GET 或 POST url: '', // 请求的 URL 地址 data: { },// 这次请求要携带的数据 success: function(res) { } // 请求成功之后的回调函数 }) 通过JQuery ajax提交表单数据(★)

步骤:

监听表单提交事件

阻止表单默认提交行为

event.preventDefault() ,阻止表单的提交和页面的跳转

快速获取表单中的数据(表单序列化,JQ的方法)

$('form').serialize()函数 或者 $('form').serializeArray()

作用:

将表单中带有 name 属性的所有参数拼成一个格式为name=value&name1=value1这样的查询字符串格式。方便我们获取表单的数据;

jquery 的 ajax 方法的data 参数能够直接识别表单序列化的数据

清空全部(JQ的方法)

$('form')[0].reset()

$('input[type=submit]').on('click', (e)=>{ //1. 替换 : 发送请求 //1. 阻止默认行为 e.preventDefault() console.log('这里要发送请求了- $.ajax'); //2. 替换 : 获取数据 // 替换方式1 : // let v1 = $('input[name=bookname]').val() // let v2 = $('input[name=author]').val() // let v3 = $('input[name=publisher]').val() // console.log(v1,v2,v3); // console.log(`bookname=${v1}&author=${v2}&publisher=${v3}`); // 方式2 : let res = $('form').serialize() console.log(res); //3. 清空 $('form')[0].reset() }) XMLHttpRequest Level2的新特性 设置 HTTP 请求的时限 xhr版本 //1. 调试 network 里面的 Slow 3G,人为降低网速 //2. 调试接口 xhr.timeout = 1000; // 单位是ms // 上面的语句,将最长等待时间设为 1000 毫秒。过了这个时限,就自动停止HTTP请求。 // 与之配套的还有一个 timeout 事件,用来指定回调函数: xhr.ontimeout = function(event){ alert('请求超时!') } jquery版本 $.ajax({ url: 'http://111.222.3.444:9999/api/getbooks', // 设置超时时间 timeout:1000, success: function (res) { console.log('res:', res); }, error:function(err){ console.log('err:',err);// 超时 } }) 通过FormData对象传输文件(★)

为了方便表单处理,HTML5 新增了一个 FormData 对象

作用有两个 ;

收集整个表单的数据 类似于 $('form').serialize() (FormData 原生JS和JQ都能使用)

上传文件

FormData对象管理表单数据 按钮 // 收集数据 //1. 拿到input, 再获取value //2. serizlize() $('form').serialize() //3. 使用 formdata //1. 创建一个空的formdata let fd = new FormData() // 这个是创建一个空的fd fd.append('username','马哥') fd.append('age',90) fd.forEach((v,k) => { console.log(v,k); }) //2. 创建一个formdata, 放一个表单,这样的话,就直接把表单数据获取了 let fd = new FormData(document.querySelector('form')) fd.forEach((v,k) => { console.log(v,k); }) 测试上传 fd 数据 按钮 // 创建 fd 并收集数据 let fd = new FormData(document.querySelector('form')) let xhr = new XMLHttpRequest() // 虽然这个接口特殊,但是能说明这样确实可以上传的 // 不需要设置请求头 xhr.open('post','http://111.222.3.444:9999/api/formdata') xhr.send(fd) xhr.onload = function () { console.log(xhr.responseText); } 原生XHR上传文件-form+name

新版 XMLHttpRequest 对象,不仅可以发送文本信息,还可以上传文件。

div { width: 400px; height: 400px; border: 1px solid #000; } img { width: 100%; height: 100%; } // 需求:使用ajax上传图片 const input = document.querySelector('input') const form = document.querySelector('form') const div = document.querySelector('div') // 让选择的文件发生了改变 input.onchange = function () { console.log('哈哈哈') // 发送ajax请求,上传图片 const xhr = new XMLHttpRequest() xhr.open('post', 'http://111.222.3.444:9999/api/upload/avatar') // 不能设置请求头 const fd = new FormData(form) xhr.send(fd) xhr.onload = function () { console.log(xhr.responseText) const res = JSON.parse(xhr.responseText) div.innerHTML = `` } } 原生XHR上传文件-input + append // 收集图片数据 name='avatar' let fd = new FormData() fd.append('avatar',this.files[0]) xhr.send(fd) 使用jQuery上传文件 $('input').on('change', function () { const fd = new FormData() fd.append('avatar', this.files[0]) $.ajax({ type: 'post', url: 'http://www.111.222.3.444:9999/api/upload/avatar', data: fd, // 不修改 Content-Type 属性,使用 FormData 默认的 Content-Type 值 contentType: false, // 不对 FormData 中的数据进行 url 编码,而是将 FormData 数据原样发送到服务器 processData: false, success(res) { console.log(res) $('div').html( `` ) }, // 用于增强xhr,必须返回一个xhr对象 xhr() { const xhr = new XMLHttpRequest() xhr.upload.onprogress = function (e) { $('progress').attr('max', e.total) $('progress').attr('value', e.loaded) } return xhr }, }) }) 文件上传进度条 Document div { width: 300px; height: 300px; border: 1px solid #000; } img { width: 100%; } let ipt=document.querySelector('input[type=file]') let div=document.querySelector('div') let progress=document.querySelector('progress') ipt.onchange= function () { progress.hidden=false let fd=new FormData(document.querySelector('form')) let xhr=new XMLHttpRequest() xhr.open('post','http://111.222.3.444:9999/api/upload/avatar') // 监听上传 xhr.upload.onprogress= function (e) { // event.loaded 已传输的数据量 // event.total 总共的数据量 console.log(e.loaded,e.total); progress.max=e.total progress.value=e.loaded } xhr.upload.onload= function () { progress.hidden=true } xhr.send(fd) xhr.onload= function () { console.log(xhr.responseText); let res=JSON.parse(xhr.responseText) div.innerHTML=`` } } Axios(★★★)

axios中文文档 www.axios-js.com/zh-cn/docs/

axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范。

特征:

从浏览器中创建 XMLHttpRequests 从 node.js 创建 http 请求 支持 Promise API 拦截请求和响应 转换请求数据和响应数据 取消请求 自动转换 JSON 数据 客户端支持防御 XSRF 请求配置

这些是创建请求时可以用的配置选项。只有 url 是必需的。如果没有指定 method,请求将默认使用 get 方法

{ // (★)`url` 是用于请求的服务器 URL url: '/user', // (★)`method` 是创建请求时使用的方法 method: 'get', // default // (★)`baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。 // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL baseURL: 'https://some-domain.com/api/', // `transformRequest` 允许在向服务器发送前,修改请求数据 // 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法 // 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream transformRequest: [function (data, headers) { // 对 data 进行任意转换处理 return data; }], // `transformResponse` 在传递给 then/catch 前,允许修改响应数据 transformResponse: [function (data) { // 对 data 进行任意转换处理 return data; }], // (★)`headers` 是即将被发送的自定义请求头 headers: {'X-Requested-With': 'XMLHttpRequest'}, // (★)`params` 是即将与请求一起发送的 URL 参数 // 必须是一个无格式对象(plain object)或 URLSearchParams 对象 params: { ID: 12345 }, // `paramsSerializer` 是一个负责 `params` 序列化的函数 // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/) paramsSerializer: function(params) { return Qs.stringify(params, {arrayFormat: 'brackets'}) }, // (★★)`data` 是作为请求主体被发送的数据 // 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH' // 在没有设置 `transformRequest` 时,必须是以下类型之一: // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams // - 浏览器专属:FormData, File, Blob // - Node 专属: Stream data: { firstName: 'Fred' }, // (★)`timeout` 指定请求超时的毫秒数(0 表示无超时时间) // 如果请求话费了超过 `timeout` 的时间,请求将被中断 timeout: 1000, // `withCredentials` 表示跨域请求时是否需要使用凭证 withCredentials: false, // default // `adapter` 允许自定义处理请求,以使测试更轻松 // 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)). adapter: function (config) { /* ... */ }, // `auth` 表示应该使用 HTTP 基础验证,并提供凭据 // 这将设置一个 `Authorization` 头,覆写掉现有的任意使用 `headers` 设置的自定义 `Authorization`头 auth: { username: 'janedoe', password: 's00pers3cret' }, // (★)`responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream' responseType: 'json', // default // `responseEncoding` indicates encoding to use for decoding responses // Note: Ignored for `responseType` of 'stream' or client-side requests responseEncoding: 'utf8', // default // `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称 xsrfCookieName: 'XSRF-TOKEN', // default // `xsrfHeaderName` is the name of the http header that carries the xsrf token value xsrfHeaderName: 'X-XSRF-TOKEN', // default // `onUploadProgress` 允许为上传处理进度事件 onUploadProgress: function (progressEvent) { // Do whatever you want with the native progress event }, // `onDownloadProgress` 允许为下载处理进度事件 onDownloadProgress: function (progressEvent) { // 对原生进度事件的处理 }, // `maxContentLength` 定义允许的响应内容的最大尺寸 maxContentLength: 2000, // `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte validateStatus: function (status) { return status >= 200 && status < 300; // default }, // `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目 // 如果设置为0,将不会 follow 任何重定向 maxRedirects: 5, // default // `socketPath` defines a UNIX Socket to be used in node.js. // e.g. '/var/run/docker.sock' to send requests to the docker daemon. // Only either `socketPath` or `proxy` can be specified. // If both are specified, `socketPath` is used. socketPath: null, // default // `httpAgent` 和 `httpsAgent` 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项: // `keepAlive` 默认没有启用 httpAgent: new http.Agent({ keepAlive: true }), httpsAgent: new https.Agent({ keepAlive: true }), // 'proxy' 定义代理服务器的主机名称和端口 // `auth` 表示 HTTP 基础验证应当用于连接代理,并提供凭据 // 这将会设置一个 `Proxy-Authorization` 头,覆写掉已有的通过使用 `header` 设置的自定义 `Proxy-Authorization` 头。 proxy: { host: '127.0.0.1', port: 9000, auth: { username: 'mikeymike', password: 'rapunz3l' } }, // `cancelToken` 指定用于取消请求的 cancel token // (查看后面的 Cancellation 这节了解更多) cancelToken: new CancelToken(function (cancel) { }) } axios发起GET请求 axios.get(url,{ headers: {}, //headers携带自定义的请求头,如token params : {} // axios.get一般将需要携带的参数拼接在url后面,也可以使用params }) 或者 axios.get(url?字符串,{ headers: {} })

代码演示

// axios.get(url,config) // 方式一:拼接在url后面,以字符串形式 axios.get('http://111.222.3.444:9999/v1/get?name=admin&pwd=123456' // 方式二:使用params,以键值对形式 axios.get('http://111.222.3.444:9999/v1/get', { params: { name: 'admin', pwd: 123456 } }).then(res => { console.log('res', res); }) axios发起POST请求 axios.post( url , data , { headers: {} //headers携带自定义的请求头,如token }) // data为axios.get携带的参数(范围极为广泛,见上面),在请求前收集好 // params:{}在axios.post形式极为罕见,不使用

代码演示

// 发表评论接口 // 第一种 : 参数是字符串 axios.post('http://111.222.3.444:9999/api/addcmt', 'username=aaaa&content=123').then(res => { console.log('res', res); }) // 第二种 : 参数是对象 axios.post('http://111.222.3.444:9999/api/addcmt', { username: 'admin', content: 123456 }).then(res => { console.log('res', res); }) 直接使用axios发起请求 (不建议使用) axios({ method: '请求类型', url: '请求的URL地址', data: { /* POST数据 */ }, params: { /* GET参数 */ } }) .then(callback) 响应结构

某个请求的响应包含以下信息

{ // `data` 由服务器提供的响应 data: {}, // `status` 来自服务器响应的 HTTP 状态码 status: 200, // `statusText` 来自服务器响应的 HTTP 状态信息 statusText: 'OK', // `headers` 服务器响应的头 headers: {}, // `config` 是为请求提供的配置信息 config: {}, // 'request' // `request` is the request that generated this response // It is the last ClientRequest instance in node.js (in redirects) // and an XMLHttpRequest instance the browser request: {} }

使用 then 时,响应如下 :

axios.get('/user/12345') .then(function(response) { console.log(response.data); console.log(response.data); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.config); }) 简写为: axios.get('/user/12345') .then(res => { console.log(res); // res对象中的数据按需使用就行 }) 全局的 axios 默认值 // 默认的baseURL,配置后请求中的url可省略baseURL不写 axios.defaults.baseURL = 'https://api.example.com'; // 默认的headers,配置后请求中的headers可不写(由于有些请求没有header,一般使用条件语句来有选择的配置) axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; // 默认的Content-Type,很少用 axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; 拦截器 // 添加请求拦截器 axios.interceptors.request.use(function (config) { // 在发送请求之前做些什么 return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); }); // 添加响应拦截器 axios.interceptors.response.use(function (response) { // 对响应数据做点什么 return response; }, function (error) { // 对响应错误做点什么 return Promise.reject(error); }); 同源和跨域 同源策略 同源的定义

同源的网站,有三个相同:协议、域名、端口

举例来说,http://www.test.com/index.html 这个网址,协议是http://,域名是www.example.com,端口是80(默认端口可以省略)。

http协议默认端口80,https默认端口443

http://www.test.com/other.html 同源(协议、域名、端口相同) https://www.test.com/about.html 协议不同(http 与 https) http://blog.test.com/movie.html 域名不同(www.test.com 与 blog.test.com) http://www.test.com:7001/home.html 端口不同(默认的 80 端口与 7001 端口) http://www.test.com:80/main.html 同源(协议、域名、端口相同) 同源的目的

保证用户信息的安全,防止恶意的网站窃取数据

跨域

违反浏览器的同源策略就是跨域

跨域时浏览器的报文 允许跨域前

console控制台报错信息:

跨域.png

network情况:

允许跨域前1.png

允许跨域前2.png

允许跨域后

console控制台无报错

network情况正常:

允许跨域后.png

允许跨域后2.png

解决跨域的方法(需要从后端入手) JSONP(较少使用)

前提:script 标签是不受同源策略的限制的,它可以载入任意地方的 JavaScript 文件,而并不要求同源。类似的还有img和link标签

原理:借助了script标签不受同源策略的限制,在服务端返回一个函数的调用,将数据作为当前调用函数的实参。 在浏览器端,需要程序要声明一个函数,通过形参就可以获取到服务端返回的对应的值。

注意点:JSONP只在get请求下有用

function success(res) { console.log(res); } CORS(较常见)

CORS(Cross-Origin Resource Sharing)跨源资源共享

CORS 的具体流程(★) 浏览器会向发送一条请求,服务器接受到请求之后,会返回请求头信息,浏览器查看返回的响应头信息中是否设置了header('Access-Control-Allow-Origin:请求源域名或者*'); 如果没有设置,说明服务器不允许使用 cors 跨域,那么浏览器会把获取到的数据拦截。 如果返回的响应头中设置了header('Access-Control-Allow-Origin:请求源域名或者*');,浏览器会跟请求头中的Origin: http://www.study.com进行对比,如果满足要求,就把数据发送给用户。 结论:跨域行为是浏览器行为,是浏览器阻止了 ajax 行为。服务器与服务器之间是不存在跨域的问题的 注意:浏览器允许发起跨域请求,但是,跨域请求回来的数据,会被浏览器拦截,无法被页面获取到!

详细见官方中文文档developer.mozilla.org/zh-CN/docs/…

跨域本质.png

jsonp 与 cors 的对比

jsonp 兼容性好,老版本浏览器也支持

缺点是只支持 GET 请求,不支持 POST 请求。

发送的数据量有限。使用麻烦

CORS:出现的较晚,它是 W3C 标准,属于跨域 Ajax 请求的根本解决方案。

支持 GET 和 POST 请求。 缺点是不兼容某些低版本的浏览器。(浏览器支持 cors 功能才行) 但是使用简单,只要服务端设置允许跨域,对于客户端来说,跟普通的 get、post 请求并没有什么区别。

跨域的安全性问题:跨域并不会带来安全性问题,因为跨域是需要服务端配合的 ,也就是说不论 jsonp 还是 cors,如果没有服务端的允许,浏览器是没法做到跨域的。

node中(后端)设置允许跨域:

方式一:

node设置允许跨域1.png

方式二:

node设置允许跨域2.png

反向代理

原理:服务器与服务器之间是不存在跨域的问题

如Nginx就是性能非常好的反向代理服务器,用来做负载均衡。

正向代理

正向代理.jpg

反向代理

反向代理.jpg

​ 反向代理的实现: ​ ①需要有一个负载均衡设备来分发用户请求,将用户请求分发到空闲的服务器上

​ ②服务器返回自己的服务到负载均衡设备

​ ③负载均衡将服务器的服务返回用户

正向代理和反向代理的区别:正向代理隐藏真实客户端,反向代理隐藏真实服务端



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3