同源政策
Ajax 只能向自己的服务器发送请求。A 网站中的 HTML 文件只能向 A 网站服务器中发送 Ajax 请求,A 网站是不能向 B 网站发送 Ajax 请求的。
使用 JSONP 解决同源限制问题
jasonp = json with padding
不属于 ajax 请求,但是可以模拟 Ajax 请求。
利用 script 标签发送请求
解决的是 get 请求,传递参数需要拼接 url
封装
客户端(浏览器端)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function jsonp(options) { var script = document.createElement('script'); var params = ''; for(var attr in options.data) { params += '&' + attr + '=' options.data[attr]; } var fnName = 'myJsonp' + Math.random().toString().replace('.', ''); window[fnName] = options.success; script.src = options.url + '?callback=' + fnName + params; document.body.appendChild(script); script.onload = function() { document.body.removeChild(script); } }
|
服务器端
服务器端使用了 Node.js 并且使用了 Node 的 Express 框架
1 2 3 4 5 6 7 8 9 10 11 12
| app.get("/better", (req, res) => {
res.jsonp({ name: "zhangsan", age: 20 }); });
|
另一种解决方法
由于同源限制只存在在浏览器中,服务器中不存在,所以跨源请求可以由服务器代发。
客户端先向自己的服务器 A 发送请求, 然后再由服务器 A 向服务器 B 发送请求,最后再传回响应。
需要安装模块 requestnpm install request
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const request = require("request");
const express = require("express"); const path = require("path");
const app = express(); app.use(express.static(path.join(__dirname, "public")));
app.get("/server", (req, res) => { request("http://localhost:3001/cross", (err, response, body) => { console.log(err); console.log(response); console.log(body); res.send(body); }); });
app.listen(3000);
|
cookie
在使用 Ajax 技术发送跨域请求时,默认情况下不会在请求中携带 cookie 信息。
客户端和服务器端都需要做相应的设置,两者缺一不可。
withCredentials: 指定在涉及跨域请求时,是否携带 cookie 信息,默认为 false
Access-Control-Allow-Credentials: true 允许客户端发送请求时携带 cookie
example:
客户端: xhr.withCredentials = true
服务端:
1 2 3 4 5 6 7
| app.use((req, res, next) => { res.header("Access-Control-Allow-Origin", "http://localhost:3000"); res.header("Access-Control-Allow-Methods", "get,post"); res.header("Access-Control-Allow-Credentials", true); next(); });
|