博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Web 跨域请求
阅读量:5270 次
发布时间:2019-06-14

本文共 5193 字,大约阅读时间需要 17 分钟。

在前端开发过程中,难免和服务端产生数据交互。一般情况我们的请求分为这么几种情况:

  1. 只关注发送,不关注接收
  2.不仅要发送,还要关注服务端返回的信息

      a.  同域请求

      b.  跨域请求

  所谓 跨域,一般情况下为三种情况:跨协议、跨子域、跨域名。下面距离梳理一下这三种情况。

跨协议:比如说我现在的域名地址是http://www.12306.cn,有一些请求需要发送到https://www.12306.cn,此时这个请求相对与http://www.12306.cn来说就是跨协议的请求

跨子域:比如说我现在是http://www.12306.cn,在登录的时候需要请求http://passport.12306.cn这个接口,此时这个请求就是跨子域的请求
跨域名:我们都知道现在的12306添加新的常用联系人的时候需要验证身份证号码,据说校验身份证号和姓名是否匹配只有公安部才有这个接口,并且使用费用相当高(扯远了),此时需要请求公安部的服务接口,此时从12306发出的请求就需要跨域名了

跨域请求只要满足这是三种情况之一就会被认定为跨域请求。

目前流行比较广的跨域请求解决方案有:window.name、document.domain、服务端代理、jsonp、前端代理。
以下介绍的方式只是实现原理,没有过多考虑安全性,可以根据自己的情况进行选择。

 

window.name

前端发送一个请求给隐藏的iframe,然后服务端每次将返回值,以js形式返回,然后iframe的父窗口获取window.name的值。服务端返回数据形式为:

 document.domain 这个使用限制条件较多,必须是不同子域间,协议和端口号必须相同。比如:a.12306.cn和b.12306.cn之间相互操作,可以分别在两个域名下定义:document.domain = '12306.cn'; 这样就实现了跨子域通信。 服务端代理 这种情况不适合跨协议通信,比较适合跨端口和跨域名。这个前端基本上相当于普通的请求,我们所要访问的接口都经过服务端的代理,我们访问的请求都是本域的。 jsonp请求 我们用的比较多,原理就是在发起请求时,动态的在页面加载一个script标签,因为src可以接收跨域资源,然后这个script标签的资源是执行一个js方法,并且将服务端返回的数据作为参数传递过来。这种情况唯一的缺点就是只能发送get请求,不适用用post请求。jsonp返回的数据格式为: callback({errno:0,errmsg:'ok'}); 前端代理 和window.name的实现比较类似,将请求发送到一个隐藏的iframe,然后服务端返回类似这样的内容:

然后proxy文件,接收到这些参数,进行处理,转化成类似与jsonp的返回值,执行页面上的回调。这种情况是可以发送post请求的。

proxy文件的内容,如下:

通过上面的介绍,简单的知道了处理跨域请求的一些方法,下面整理了一个基于jquery的,解决跨域的方法。

$(function() {	'use strict';	/**	 * 交互类	 * @param {object} param 要提交的数据	 * @param {Object} [ajaxOpt] ajax配置	 * @param {boolean} [https=false] 是否使用https协议	 * @constructor	 */	var Sync = function(param, ajaxOpt, https) {		var protocol = this.protocol = https ? 'https': 'http';		var ajaxOptDefault = {			url: protocol + '://'+location.host,			type: 'GET',			dataType: 'jsonp',			timeout: 20000		};		param = string2JSON(param) || {};		this.protocol = protocol;		this.param = $.extend({}, param, ajaxOpt);		this.ajaxOpt = $.extend({data: this.param}, ajaxOptDefault);		this.HOST = protocol + '://'+location.host;	};	function string2JSON(str){		if($.isPlainObject(str)) {			return str;		}		var params = {};		var str2Arr = str.split('&');		$.each(str2Arr, function(i, keyVal) {			var arr = keyVal.split('=');			//去除serialize把空格转成+			params[arr[0]] = decodeURIComponent(arr[1]).replace(/[\+]+/, '').replace(/[\+]+/, '');		});		return params;	}	$.extend(Sync.prototype, {		/**		 * 通过get方式(jsonp)提交		 * @param {String} [url] 请求链接		 * @return {Object} promise对象		 */		get: function(url) {			var self = this;			var send = $.ajax(url, this.ajaxOpt);			return send.then(this.done, function(statues) {				return self.fail(statues);			});		},		/**		 * 通过post方式提交,依赖psp_jump.html文件		 * @param {String} [url] 请求链接		 * @return {Object} promise对象		 */		post: function(url) {			var deferred = $.Deferred();			var timer = null;			var guid = parseInt(new Date().getTime().toString().substr(4), 10);			var funName =  'QBXJsonp' + guid;			var formName = 'QBXForm' + guid;			var iframeName = 'QBXIframe' + guid;			// iframe 不能使用attr('name', xxx) 否则在ie7上添加的不是name属性而是submitName			var iframe = $('

 

至此就可以做到跨域请求了

 

转载于:https://www.cnblogs.com/wisdo/p/4267740.html

你可能感兴趣的文章
CF219D Choosing Capital for Treeland
查看>>
杂七杂八的小笔记本
查看>>
51Nod1353 树
查看>>
CF1215E Marbles
查看>>
BZOJ2339 HNOI2011卡农(动态规划+组合数学)
查看>>
octave基本操作
查看>>
axure学习点
查看>>
WPF文本框只允许输入数字[转]
查看>>
dom4j 通用解析器,解析成List<Map<String,Object>>
查看>>
第一个项目--用bootstrap实现美工设计的首页
查看>>
使用XML传递数据
查看>>
TYVJ.1864.[Poetize I]守卫者的挑战(概率DP)
查看>>
0925 韩顺平java视频
查看>>
iOS-程序启动原理和UIApplication
查看>>
mysql 8.0 zip包安装
查看>>
awk 统计
查看>>
CSS min-height 属性
查看>>
模板设计模式的应用
查看>>
实训第五天
查看>>
平台维护流程
查看>>