问题引出:要发送Ajax请求,就必须使用HTTP请求?什么是跨域问题?

什么是跨域问题:如果两个页面中的协议、域名、端口、子域名任意有一项不同,两者之间所进行的访问行动就是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。

如何解决呢?

1. 使用创建DOM元素的方式创建img对象, audio, video, link 这几个对象都支持跨域请求,。
var img = new Image();
img.src = 'http://192.168.1.105:8080?name=zhangsan&age=18';

类似于上面的这种呢?还有其他一些类似的标签,实际上是可以向服务器发送请求的,但是不能拿到返回值

2.  使用link标签, 但是也不能拿到服务器的请求, 然后再试试script这个标签来试试看???

<link rel="stylesheet" href="">

link标签只能支持css的格式,其他格式的内容浏览器是显示不出来的

3. 使用script标签来实现跨域, 也能满足发送数据的要求, 接受数据呢?来测试一下。

 var script = document.createElement('script');
script.src = 'http://192.168.1.105:8080?name=zhangsan&age=18';
document.body.appendChild(script); // 开始正式发送请求

经测试,还是真可以的,而且在客户端也成功接受到了数据,这说明我们终于找对了路!

4. 解决没有加载完成就输出的问题( 这样就会等待到script标签加载完成之后执行)

 // 在返回数据到客户端之前,先进行字符串拼接
let json = JSON.stringify({
id: 1,
name: 'zhangsan',
age: 18,
gender: 'Male'
}); let jsonStr = 'var data = ' + json;

上面的是我们服务器的数据, 我们直接通过字符串拼接json,然后发给浏览器。

console.log(data)

直接输出,我们发现报错了,找不到这个变量???

原因是因为,浏览器自上而下执行代码,如果DOM元素没有加载完毕就输出,坑定会报错的

5.解决没有加载完成就输出的问题( 这样就会等待到script标签加载完成之后执行)
script.addEventListener('load', function () {
console.log(data);
});

直接绑定个事件不就行了,测试以后还真是可以。

但是,缺点是: 这种方式需要服务器端定义一个全局变量, 从而会污染全局变量, 不太推荐…………

 6. 上面的思路逻辑和代码优化, 由于脚本执行过后才可以拿到数据, 上面的代码可以优化吗?
var script = document.createElement('script');
script.src = 'http://192.168.1.105:8080?name=zhangsan&age=18';
document.body.appendChild(script); function callback(data) {
console.log(data)
}

实现原理: 服务器端实际上是返回了一个callback函数的调用, 类似于callback(jsondata), 因此当且仅当服务器断点数据返回来以后, 下面的这个函数就相当于是自动调用了, 就会直接得到服务器端传回来的数据信息, 从而打印输出数据。

服务器端就是这样的:

    let jsonFunc = `callback(${json})`;

7. 代码的继续优化, 可以直接在请求中, 我要自己定义一个函数呢?函数名我要自己指定的方法, 可以直接写在url请求中。

 var script1 = document.createElement('script');
var url = 'http://192.168.1.105:8080?name=zhangsan&age=19&callback=callback1';
script1.src = url;
document.body.appendChild(script1);
function callback1(data) {
console.log(data);
}

服务器端进行参数解析,换成用户自己定义的函数名字不就行了?

 let callback = urlObj.query.callback;

let jsonFunc = ''+callback+'' + '('+ json + ')';

到此,浏览器的跨域问题已经基本全部解决。

【JavaScript】通过封装自己的JSONP解决浏览器的跨域问题(Ajax跨域)的更多相关文章

  1. JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  2. 【转】JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  3. 通过jsonp解决浏览器的跨域共享

    因为浏览器的同源策略,普通ajax访问跨域请求返回的json数据是不会被浏览器接受的.看下面例子可以看出是访问不到的 首先 定义webapi 后台代码 public class JsopControl ...

  4. Ajax跨域:Jsonp原理解析

    推荐先看下这篇文章:JS跨域(ajax跨域.iframe跨域)解决方法及原理详解(jsonp) JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重 ...

  5. 解决浏览器跨域限制方案之JSONP

    一.什么是JSONP JSONP即:JSON with Padding,是一种解决因浏览器跨域限制不允许访问跨域资源的方法. JSONP是一个非官方的协议,它允许在服务器端返回javascript标签 ...

  6. jQuery(三) javascript跨域问题(JSONP解决)

    加油~ --WH 一.什么是javascript跨域问题? 域:服务器域名,唯一标识(协议,域名,端口)必须保证一致,说明域相同 跨域:在一个服务器上,去访问另一个服务器上,并且得到另一个服务器返回回 ...

  7. 第一百四十节,JavaScript,封装库--浏览器检测

    JavaScript,封装库--浏览器检测 在函数库编写一个,浏览器检测对象 /** sys浏览器检测对象,对象下有两个属性,liu_lan_qi属性和xi_tong属性 * liu_lan_qi属性 ...

  8. JavaScript 跨域:谈谈跨域之 JSONP

    在 Web 开发中,后台开发人员应该会通常遇到这个问题:跨域,而使用 JSONP 就是其中解决办法之一,当然,还有其它解决方法,比如:window.name.window.postMessage.CO ...

  9. 说说JSON和JSONP,浅析JSONP解决AJAX跨域问题

    说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决?这两个问题目前都有不同的解决方案,比如数据可以用自定义字符串或者用XML来描述,跨域可以通过服 ...

随机推荐

  1. shell中eval命令

    原文:http://www.cnblogs.com/xdzone/archive/2011/03/15/1984971.html 语法:eval cmdLine eval会对后面的cmdLine进行两 ...

  2. HDU2899 Strange fuction 【二分】

    Strange fuction Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  3. 软件project文档中的数据库模型设计

    背景:软件project文档之<数据库设计说明书>的结构设计部分要明白规划出数据库的概念结构设计.逻辑结构设计.物理结构设计,就是设计数据库的概念模型.逻辑模型.物理模型.那么.何为数据库 ...

  4. 使用Django框架实现游戏站点搭建

    完整project链接点击打开链接 上一篇中我们使用了Javascript和Html5实现了弹球游戏.而在本文中我们希望以其为基础实现游戏站点,可以实现用户的注冊登录.游戏成绩记录,排名显示.微博分享 ...

  5. 学习笔记——node.js

    node.js的作用在于,号称可以让服务器支持更多的连接.比如说,php + apche可以让服务器支持4000个并发连接,那么node.js + apche可以让服务器支持并发几万个. 为什么这么牛 ...

  6. 阿里云 Docker-registry 搭建

    阿里云 仓库地址: https://cr.console.aliyun.com/cn-hangzhou/instances/images

  7. Android TextView 设置行间距

    Android系统中TextView默认显示中文时会比较紧凑,不是很美观.为了让每行保持一定的行间距,可以设置属性android:lineSpacingExtra或android:lineSpacin ...

  8. diff比较两个文件的差异

    1.diff -ruN a.txt b.txt>patch.txt比较第二个文件与第一个文件相比的变化,并将变化添加到patch.txt文件中,-表示删除的行,+表示添加的行 2.下面的,“&l ...

  9. 机器学习——Day 2 简单线性回归

    写在开头 由于某些原因开始了机器学习,为了更好的理解和深入的思考(记录)所以开始写博客. 学习教程来源于github的Avik-Jain的100-Days-Of-MLCode 英文版:https:// ...

  10. MarkDown流程图概要

    要素 流程元素定义: 名称=>类型: 显示名称 控制流程定义: 名称1([yes,no],right)->名称2 注意事项 流程元素定义在代码上部, 流程走向定义在代码下部 名称可以取中文 ...