欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

关于跨域的一些问题(易懂)

程序员文章站 2022-03-21 12:49:18
JSONP因为ajax直接请求普通文件存在跨域问题(同源下的js发起的ajax请求是可以跨域的),甭管是啥只要是跨域请求一律都不行****但是web页面上调用js文件时不受跨域影响(而且有src的标签都有跨域的能力)所以在远程服务器上把数据装进js格式里,而JSON可以简洁描述复杂数据,并且被js原生支持。所以在服务端动态生成JSON文件并把客户端需要的数据装进去客户端调用JSON文件成功后,获得数据。这种方式很像ajax但其实不是JSONP协议允许的是用户传递callback参数给服务端,服务...

JSONP
因为ajax直接请求普通文件存在跨域问题(同源下的js发起的ajax请求是可以跨域的),甭管是啥只要是跨域请求一律都不行
****但是web页面上调用js文件时不受跨域影响(而且有src的标签都有跨域的能力)
所以在远程服务器上把数据装进js格式里,而JSON可以简洁描述复杂数据,并且被
js原生支持。所以在服务端动态生成JSON文件并把客户端需要的数据装进去
客户端调用JSON文件成功后,获得数据。这种方式很像ajax但其实不是
JSONP协议允许的是用户传递callback参数给服务端,服务端返回数据将这个callback
参数作为函数包裹住JSON数据
详见:

AAA.COM域上的文件

后端
public class JsonpServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(“text/html”);
//获取传过来的回调函数名称
String callBackName = request.getParameter(“callBack”);
//处理业务逻辑拼接json串
String json = “{“name”:“jack”,“sex”:“man”}”;
//设置响应类型
response.setContentType(“application/json”);
//将json数据返回给请求页面
response.getWriter().write(callBackName + “(” + json + “)”);
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    doGet(request, response);
}

}


同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,
它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS.CSFR等攻击。
所谓同源是指”协议+域名+端口”三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
同源策略限制以下几种行为(就是说不同源的话):


1.) Cookie.LocalStorage 和 IndexDB 无法读取
2.) DOM 和 Js对象无法获得
3.) AJAX 请求不能发送

要注意同源的情况也是可以跨域的(同源是你协议域名端口一样啊只要一样无论你在那都能跨域)

这些都算
1.) 资源跳转: A链接.重定向.表单提交
2.) 资源嵌入: <link>.<script>.<img>.<frame>等dom标签,还有样式中background:url().@font-face()等文件外链
3.) 脚本请求: js发起的ajax请求.dom和js对象的跨域操作等

跨域解决方案 (我不同源的情况下夸不了域啊,这时我的解决方案)


1、通过jsonp跨域

用jQuery ajax写的话
$.ajax({
url: ‘http://www.domain2.com:8080/login’,
type: ‘get’, //jsonp的ajax只能get请求
dataType: ‘jsonp’, // 请求方式为jsonp
jsonpCallback: “onBack”, // 自定义回调函数名
data: {}
});

用vue写JSONP的话
this.$http.jsonp(‘http://www.domain2.com:8080/login’, {
params: {},
jsonp: ‘onBack’
}).then((res) => {
console.log(res);
})
后端
var querystring = require(‘querystring’);
var http = require(‘http’);
var server = http.createServer();

server.on(‘request’, function(req, res) {
var params = qs.parse(req.url.split(’?’)[1]);
var fn = params.callback;

// jsonp返回设置
res.writeHead(200, { 'Content-Type': 'text/javascript' });
res.write(fn + '(' + JSON.stringify(params) + ')');

res.end();

});
server.listen(‘8080’);
console.log(‘Server is running at port 8080…’);

2、document.domain + iframe跨域
3、location.hash + iframe
4、window.name + iframe跨域
5、postMessage跨域
***6、跨域资源共享(CORS)(主流方案)
普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置。
带cookie请求:前后端都需要设置字段,另外需注意:所带cookie为跨域请求接口所在域的cookie,而非当前页。
目前,所有浏览器都支持该功能(IE8+:IE8/9需要使用XDomainRequest对象来支持CORS)),CORS也已经成为主流的跨域解决方案
原生ajax写法
var xhr = new XMLHttpRequest(); // 这就是F12里的XHR就是原生的ajax表达

// 前端设置是否带cookie
xhr.withCredentials = true;

xhr.open(‘post’, ‘http://www.domain2.com:8080/login’, true);
xhr.setRequestHeader(‘Content-Type’, ‘application/x-www-form-urlencoded’);
xhr.send(‘user=admin’);

xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
};
jQuery ajax实现跨域
$.ajax({

xhrFields: {
withCredentials: true // 前端设置是否带cookie
},
crossDomain: true, // 会让请求头中包含跨域的额外信息,但不会含cookie

});
vue实现cors跨域

vue框架在vue-resource封装的ajax组件中加入以下代码:
Vue.http.options.credentials = true

node后端
var http = require(‘http’);
var server = http.createServer();
var qs = require(‘querystring’);

server.on(‘request’, function(req, res) {
var postData = ‘’;

// 数据块接收中
req.addListener('data', function(chunk) {
    postData += chunk;
});

// 数据接收完毕
req.addListener('end', function() {
    postData = qs.parse(postData);

    // 跨域后台设置
    res.writeHead(200, {
        'Access-Control-Allow-Credentials': 'true',     // 后端允许发送Cookie
        'Access-Control-Allow-Origin': 'http://www.domain1.com',    // 允许访问的域(协议+域名+端口)
        'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly'   // HttpOnly:脚本无法读取cookie
    });

    res.write(JSON.stringify(postData));
    res.end();
});

});

server.listen(‘8080’);
console.log(‘Server is running at port 8080…’);

listen后面的就是我们所监听的那个源,只要是这个地址的就OK。不是的话好比用JSONP跨域。我只要在js标签里
做一些操作,让后台可以对接,那就没问题

7、nginx代理跨域

  1. Nginx配置解决iconfont跨域

浏览器跨域访问js.css.img等常规静态资源被同源策略许可,但iconfont字体文件(eot|otf|ttf|woff|svg)例外,此时可在nginx的静态资源服务器中加入以下配置。

location / {
add_header Access-Control-Allow-Origin *;
}

  1. Nginx反向代理接口跨域

跨域原理: 同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,
不会执行JS脚本,不需要同源策略,也就不存在跨越问题。
实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,
反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,
实现跨域登录。
8、nodejs中间件代理跨域
原理和NGINX大致相同
9、WebSocket协议跨域
WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,
是server push技术的一种很好的实现。原生WebSocket API使用起来不太方便,我们使用Socket.io,
它很好地封装了webSocket接口,提供了更简单.灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。
不建议 一般接口也不会使用WebSocket形式

SDK
最开始的时候,API的集合我们就称之为SDK,例如mac提供的API集合,就称之为mac SDK。
随着时间的演化,现在的SDK指的是以一组Api作为输入,以另外一组Api作为输出的中间件。

SDK是一些被软件工程师用于为特定的软件包、软件框架、硬件平台、操作系统等创建应用软件的开发工具的集合。
它可以简单的为某个程序设计语言提供应用程序接口API的一些文件,但也可能包括能与某种嵌入式系统通讯的复杂的硬件。
SDK还经常包括示例代码、支持性的技术注解或者其他的为基本参考资料澄清疑点的支持文档。

本文地址:https://blog.csdn.net/qq_46311036/article/details/109378994

相关标签: 前端