foreword
In the process of daily project development, cross-domain and how to solve cross-domain problems are topics that cannot be avoided by front-end and back-end development students. JSONP cross-domain is a classic solution to cross-domain problems.
💡Warm reminder: The full text of this article is 1921 words. The recommended reading time is 10min. Come on, old iron!
First, the same-origin policy and cross-domain
1.1 Same Origin Policy
1.1.1 What is homology
Two pages have the same source if 协议
, 域名
and 端口
are the same.<br>For example, the following table gives the relative Homologous detection on the http://www.test.com/index.html
page:
1.1.2 What is the Same Origin Policy
Same origin policy (English full name Same origin policy) is a security feature provided by browsers.
The concept officially given by MDN: the same-origin policy restricts how a document or script loaded from the same origin can interact with resources from another origin. This is an important security mechanism for isolating potentially malicious files.
Popular understanding: the browser stipulates that the JavaScript of the A website does not allow the interaction of resources with the non-same-origin website C, for example:
- Unable to read
Cookie
,LocalStorage
andIndexedDB
of non-homologous web pages - Unable to access non-homologous web pages
DOM
- Unable to send
AJAX
request to non-same origin address
1.2 Cross-domain
1.2.1 What is cross domain
Homologous means that the two URLs 协议
, 域名
, --- b9e4587618e5819ff44a0fc717debffa 端口
are consistent, and vice versa.
The root cause of cross-origin: the browser's same-origin policy does not allow resource interaction between non-same-origin URLs.
Web page: http://www.test.com/index.html
Interface: http://www.api.com/userlist
1.2.2 Browser interception of cross-domain requests
Note: Browsers are allowed to initiate cross-domain requests, but the data returned by cross-domain requests will be intercepted by the browser and cannot be obtained by the page !
1.2.3 How to implement cross-domain data request
实现跨域数据请求方法有很多,比如JSONP
、 CORS
、 postMessage
、 Websocket
、 Nginx反向代理
、 window.name + iframe
, document.domain + iframe
, location.hash + iframe
etc. The three main solutions are JSONP and CORS and Nginx reverse proxy.
- JSONP : It appeared early and has good compatibility (compatible with lower versions of IE). It is a temporary solution that front-end programmers are forced to come up with in order to solve cross-domain problems. The disadvantage is that only
GET
POST
are not supported. - CORS : It's a late comer, it's a W3C standard, and it's a fundamental solution for cross-domain
AJAX
requests.GET
andPOST
requests are supported. The disadvantage is that it is not compatible with some lower version browsers. - Nginx reverse proxy : The same-origin policy does not limit the server and is the simplest cross-domain method. You only need to modify the configuration of nginx to solve the cross-domain problem, support all browsers, support
session
, do not need to modify any code, and will not affect server performance.
2. Overview of JSONP
JSONP (JSON with Padding) is a "usage pattern" of JSON that can be used to solve the problem of cross-domain data access by mainstream browsers.
2.1 The principle of JSONP
Define a callback function for obtaining cross-domain response data in advance, and initiate a request through the script
tag that is not restricted by the same-origin policy (put the name of the callback function in the request's query
parameter), then the server returns the execution of this callback function, and puts the data to be responded into the parameters of the callback function, the front-end script
tag request to this callback function will be executed immediately after the execution , so the response data of the execution is obtained.
2.2 Advantages
- It is not restricted by the same-origin policy as the
XMLHttpRequest
object implements theAjax
request - It's more compatible, works in older browsers, doesn't require
XMLHttpRequest
orActiveX
support - And after the request is completed, the result can be returned by calling
callback
2.3 Disadvantages
- It only supports
GET
request but notPOST
and other types of HTTP requests - It only supports cross-domain HTTP requests, and cannot solve the problem of how to make JavaScript calls between two pages of different domains
3. JSONP application process
Set a
script
tag<script src="http://jsonp.js?callback=cb"></script> // 或 let script = document.createElement('script'); script.src = "http://jsonp.js?callback=cb"; body.append(script)
-
callback
defines a function name, and the remote server passes the parameters by calling the specified function and passing in the parameters, and passes thefunction(response)
back to the client
router.get('/', function (req, res, next) {
(() => {
const data = {
x: 10
};
let params = req.query;
if (params.callback) {
let callback = params.callback;
console.log(params.callback);
res.send(`${callback}(${JSON.stringify(data.x)})`);
} else {
res.send('err');
}
})();
});
- The client receives the returned JS script and starts parsing and executing
function(response)
Fourth, JSONP implementation
3.1 Simple example:
A simple JSONP implementation is actually splicing URL
, and then dynamically adding a script
element to the header.
Front-end JSONP method example:
function jsonp(req) {
var script = document.createElement('script');
var url = req.url + '?callback=' + req.callback.name;
script.src = url;
document.getElementsByTagName('head')[0].appendChild(script);
}
Front-end JS example:
function hello(res){
alert('hello ' + res.data);
}
jsonp({
url : '',
callback : hello
});
Server side code:
var http = require('http');
var urllib = require('url');
var port = 8080;
var data = {'data':'world'};
http.createServer(function(req,res){
var params = urllib.parse(req.url,true);
if(params.query.callback){
console.log(params.query.callback);
// jsonp
var str = params.query.callback + '(' + JSON.stringify(data) + ')';
res.end(str);
} else {
res.end();
}
}).listen(port,function(){
console.log('jsonp server is on');
});
3.2 Reliable JSONP instance:
(function (global) {
var id = 0,
container = document.getElementsByTagName("head")[0];
function jsonp(options) {
if(!options || !options.url) return;
var scriptNode = document.createElement("script"),
data = options.data || {},
url = options.url,
callback = options.callback,
fnName = "jsonp" + id++;
// 添加回调函数
data["callback"] = fnName;
// 拼接url
var params = [];
for (var key in data) {
params.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
}
url = url.indexOf("?") > 0 ? (url + "&") : (url + "?");
url += params.join("&");
scriptNode.src = url;
// 传递的是一个匿名的回调函数,要执行的话,暴露为一个全局方法
global[fnName] = function (ret) {
callback && callback(ret);
container.removeChild(scriptNode);
delete global[fnName];
}
// 出错处理
scriptNode.onerror = function () {
callback && callback({error:"error"});
container.removeChild(scriptNode);
global[fnName] && delete global[fnName];
}
scriptNode.type = "text/javascript";
container.appendChild(scriptNode)
}
global.jsonp = jsonp;
})(this);
Example of use:
jsonp({
url : "www.example.com",
data : {id : 1},
callback : function (ret) {
console.log(ret);
}
});
Five, JSONP security issues
5.1 CSRF attack
The front-end constructs a malicious page, requests the JSONP interface, and collects sensitive information on the server. If the JSONP interface also involves some sensitive operations or information (such as login, delete, etc.), it is even less secure.
Solution : Verify the calling source of JSONP ( Referer
), and the server judges whether Referer
is a whitelist, or deploy random Token
for defense.
5.2 XSS Vulnerability
不content-type
XSS
,想象一下JSONP 就是你请求http://abc.com?callback=douniwan
, 然后返回douniwan({ data })
,那假如请求http://abc.com?callback=<script>alert(1)</script>
If not, it will return <script>alert(1)</script>({ data })
, if it is not strictly defined Content-Type( Content-Type: application/json )
, directly as HTML parameter callback
, is a naked XSS
.
解决方法: Content-Type: application/json
,然后严格过滤callback
后的参数并且限制长度(进行字符转义, <
<
, >
to >
), etc., the returned script content will be in text format, and the script will not be executed.
5.3 The server is hacked and a string of maliciously executed code is returned
The executed code can be forwarded to the server to verify the JSONP content, and then return the verification result.
refer to
JSONP security that front-ends also need to know about
Cross-domain and JSONP_Small Blog - CSDN Blog
Cross-domain resource sharing CORS detailed explanation - Ruan Yifeng's network log
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。