目录
==> 后端给前端返回的码是乱码,如何解决?
答:总共两种方法:
1、在数据包中写数据的类型
res.setHeader("content-Type","text/html;charset=utf8")
2、发一个字符串,这个字符串是一个网页的编码
比如是一个html文件,这个html里面有
它会监听代码文件的改变 然后自动重新加载。自己就不用每次去重启小黑窗了
安装:npm i nodemon -g
使用:nodemon xxx.js
跨域:
浏览器为了用户的信息安全,网页中有一个网络请求技术:AJAX 在网络请求时,请求的网址和当前页面的网址,不是同一台服务器,就会被拒绝接受服务器发送的数据
在这两个条件下,才会跨域:非同源、AJAX
同源策略:
为了网络安全,浏览器有一个同源策略
两个网址的 协议、ip、port三者一样就代表同源,后面的pathname、query可以不一样
协议 ip 端口 三者只要有一个不一样 就不允许用ajax跨域访问数据异源资源
(域名:ip+端口/port)
(如果协议、ip、port三者一样,就代表是同一个服务器)
eg:
1、同源
http://www.baidu.com/index.html 去请求==> http://www.baidu.com/home/ajax1
2、异源
http://www.baidu.com/index.html 去请求==> https://www.baidu.com/home/ajax1
3、异源
http://www.baidu.com/index.html //假设DNS解析为172.153.2.60:7001
去请求==>http://172.153.2.60:7001/ajax
跨域报错:No 'Access-Control-Allow-Origin'
浏览器中网络请求,只有AJAX才跨域的限制
这些网络请求技术不会被跨域限制:a标签 img标签 link标签 ***-url sricpt-src form-action 浏览器的地址栏
JSON with padding
对JSONP的理解:
1.前端网页中用ajax请求跨域服务器的网址 会报跨域错误
用script标签的src属性去请求跨域服务器的网址 不会报跨域错误,但是 会直接把请求过来的编码用v8引擎去运行
2. 我们可以在后端写一个js引擎能识别的字符串发送给前端,这个字符串是这样的:
' fn({"name":"karen"}) '
前端可以用script标签的src属性去请求这个网址,请求完毕以后 v8就会直接运行这个编码 去调用fn函数,所以我们必须提前创建这个函数
3.函数的名称问题: 前端可以通过querystring把函数名以参数的形式发送给后端
后端解析了以后 直接拼接到数据中(比如那个fn)
必须后端工程师配合,写出JDONP数据,前端才能用script标签请求得到数据
前端提前声明一个全局函数
利用script的src去加载后端的jsonp接口url上携带jsonp接口参数:假设是cb,也就是传参的参数名必须是cb
- //自己设计jsonp网络请求工具
- function myjsonptool (url,callback) {
- window.fm=function(arg) {
- // console.log(arg)
- callback(arg)
- }
- var sr=document.createElement("script")
- sr.src=url+"fm"
- document.body.appendChild(sr)
- }
- //使用自己设计的jsonp请求工具
- myjsonptool("(http://localhost:81/mydata?cb=",(data)=>{})
后端在给前端传输数据前,解析前端传过来的参数 取出cb字段 当做一个函数名
后端在给前端传输数据时,把json数据放在这个函数的调用里 然后把整个字符换传给前端
- //后端接口
- myjsonp(req, res) {
- let cb=解析前端传过来的cb字段
- res.end(`${cb}({name:"karen"})`)
- }
优化:
在被访问的后端代码index.js中写:
var router=require("./router.js") var fs=require("fs") var url=require("url") var querystring=require("querystring") router.get("/ajax1",function(req,res){ var obj={name:"karen",age:20,books:["css","js","node"]} var str=JSON.stringify(obj) //将对象obj转为JSON字符串 let query1=url.parse(req.url).query //得到query字符串 var querobj=querystring.parse(query1) //得到query对象 res.end(`${querobj.callback}(${str})`) //querobj.callback就取到了全局变量的那个名字,然后用它来调用函数,参数就是后端要发送的数据 })在要去访问的前端index.html代码中写:
<script> function looka(){ var name1="mingzi"+new Date().getTime() //确保取的名字不和别的重复 window[name1]=function(arg){ //声明一个全局变量 name1 console.log(arg) } var script1=document.createElement("script") //创建一个script标签 script1.src=`http://192.168.6.60:8080/ajax1?callback=${name1}` //将需要访问的网址加入到script标签中.让全局变量的名字等于url中的query的一部分 document.body.append(script1) } script>
(delegate==>也是代理的意思)
就是一个服务器请求一个服务器,没有直接请求,而是中间经过一个服务器去访问,这就是代理服务器
1、钓鱼网站--违法
前端请求后端
后端请别的网页数据 然后修改了 发给用户
2、 大数据分析
后端请别的ajax网址数据 数据处理 发给用户
3、爬虫--灰色
后端请别的静态文件和数据 数据处理 发给用户
4、 Proxy 代理服务
后端合法的去请求别的后端(oAuth授权-token) 再发给前端 前端写成自己的页面
自己的前端页面请求自己的后端ajax接口(没有问题)
利用后端去请求别的服务器的ajax接口(没有跨域限制)
再把请求的数据发送给自己的前端页面
主要用到后端的request第三方模块==>request模块后端可以做网络请求
request做网络请求,属于后端node再做网络请求,它不是AJAX,因此它请求别人的服务器的接口都没有跨域限制
request.get(url,(err,status,body)=>{})//get请求
request.post(url,(err,status,body)=>{})//post请求
request(url,(err,status,body)=>{})//默认get
在自己的后端index.js文件中:
(先下载request模块 npm i request)
- var router=require("./router.js")
- var request=require("request")//是一个后端的网络请求工具
- router.get("/home",function(req,res){
- //用户输我的网址:192.168.1.11:8080/home,但是却来到了百度的页面,但是是一个假的百度网页
- request("http://www.baidu.com/index.html",function(res,state,data){
- res.end(data) //data是html网页的代码
- //这个data可以在前端进行处理,就是在AJAX的监听那里判断是否等于4和状态码等后,就对data进行处理,将数据进行DOM渲染到页面
- })
在数据包的头部配置Access-Control-Allow-Origin字段以后,数据包发送给浏览器后
浏览器就会根据这里配置的白名单 "放行" 允许白名单的服务器对应的网页来用ajax跨域访问
ps:跨域请求 时 前端是请求了跨域的后端,只是返回的数据被浏览器拒收了,并不是跨域了就不发网络请求
在需要被访问的服务器的后端index.js里面的router.get里面的函数
res.setHeader( 'Access-Control-Allow-Origin' , 'http://192.168.1.10/8081')
但是上面的方法不好,因为只要一换ip就要重写代码,所以可以像下面这样写。
(一般在开发阶段才这样写,才允许别人跨域我的数据(谁都可以跨域我),等开发完后,就将代码删除了)
//后端设置数据包配置 允许跨域资源共享 res.setHeader( 'Access-Control-Allow-Origin' , '*')origin可以改单词,比如去判断不同的方法(get、post等等),哪种方法可以跨域
- document.domain + iframe
- location.hash + iframe
- window.name + iframe
- postMessage
- nginx
- WebSocket