JavaScript tự động gọi hàm từ chuỗi

JavaScript giúp dễ dàng tra cứu các thuộc tính đối tượng một cách linh hoạt trong thời gian chạy. Cụ thể, các phương thức có thể được tra cứu theo tên và sau đó được gọi. Tuy nhiên, nếu tên phương thức do người dùng kiểm soát, kẻ tấn công có thể chọn một tên khiến ứng dụng gọi một phương thức không mong muốn, điều này có thể gây ra ngoại lệ thời gian chạy. Nếu ngoại lệ này không được xử lý, nó có thể được sử dụng để tấn công từ chối dịch vụ

Ví dụ: có thể không có phương thức của tên đã cho hoặc kết quả tra cứu có thể không phải là hàm. Trong cả hai trường hợp, cuộc gọi phương thức sẽ ném một TypeError vào thời gian chạy

Một ví dụ khác, tinh tế hơn là kết quả tra cứu là một phương thức thư viện tiêu chuẩn từ Object.prototype, mà hầu hết các đối tượng đều có trong chuỗi nguyên mẫu của chúng. Ví dụ về các phương pháp như vậy bao gồm valueOf, hasOwnProperty__defineSetter__. Nếu lệnh gọi phương thức chuyển sai số hoặc loại đối số cho các phương thức này, chúng sẽ đưa ra một ngoại lệ

Sự giới thiệu

Tốt nhất là tránh hoàn toàn tra cứu phương thức động liên quan đến các tên do người dùng kiểm soát, chẳng hạn bằng cách sử dụng một Map thay vì một đối tượng đơn giản

Nếu không thể tránh tra cứu phương thức động, hãy xem xét đưa tên phương thức được phép vào danh sách trắng. Ít nhất, hãy kiểm tra xem phương thức đó có phải là thuộc tính riêng và không được kế thừa từ đối tượng nguyên mẫu không. Nếu đối tượng mà phương thức được tra cứu chứa các thuộc tính không phải là phương thức, bạn nên kiểm tra thêm xem kết quả tra cứu có phải là một hàm không. Ngay cả khi đối tượng chỉ chứa các phương thức, bạn vẫn nên thực hiện kiểm tra này trong trường hợp các thuộc tính khác được thêm vào đối tượng sau này

Thí dụ

Trong ví dụ sau, một thuộc tính tham số yêu cầu HTTP

var express = require('express');
var app = express();

var actions = {
  play(data) {
    // ...
  },
  pause(data) {
    // ...
  }
}

app.get('/perform/:action/:payload', function(req, res) {
  let action = actions[req.params.action];
  // BAD: `action` may not be a function
  res.end(action(req.params.payload));
});
0 được sử dụng để tra cứu động một hàm trong bản đồ
var express = require('express');
var app = express();

var actions = {
  play(data) {
    // ...
  },
  pause(data) {
    // ...
  }
}

app.get('/perform/:action/:payload', function(req, res) {
  let action = actions[req.params.action];
  // BAD: `action` may not be a function
  res.end(action(req.params.payload));
});
1, sau đó được gọi với tham số
var express = require('express');
var app = express();

var actions = {
  play(data) {
    // ...
  },
  pause(data) {
    // ...
  }
}

app.get('/perform/:action/:payload', function(req, res) {
  let action = actions[req.params.action];
  // BAD: `action` may not be a function
  res.end(action(req.params.payload));
});
2 làm đối số của nó

var express = require('express');
var app = express();

var actions = {
  play(data) {
    // ...
  },
  pause(data) {
    // ...
  }
}

app.get('/perform/:action/:payload', function(req, res) {
  let action = actions[req.params.action];
  // BAD: `action` may not be a function
  res.end(action(req.params.payload));
});

Mục đích là để cho phép khách hàng gọi phương thức

var express = require('express');
var app = express();

var actions = {
  play(data) {
    // ...
  },
  pause(data) {
    // ...
  }
}

app.get('/perform/:action/:payload', function(req, res) {
  let action = actions[req.params.action];
  // BAD: `action` may not be a function
  res.end(action(req.params.payload));
});
3 hoặc
var express = require('express');
var app = express();

var actions = {
  play(data) {
    // ...
  },
  pause(data) {
    // ...
  }
}

app.get('/perform/:action/:payload', function(req, res) {
  let action = actions[req.params.action];
  // BAD: `action` may not be a function
  res.end(action(req.params.payload));
});
4, nhưng không kiểm tra xem
var express = require('express');
var app = express();

var actions = {
  play(data) {
    // ...
  },
  pause(data) {
    // ...
  }
}

app.get('/perform/:action/:payload', function(req, res) {
  let action = actions[req.params.action];
  // BAD: `action` may not be a function
  res.end(action(req.params.payload));
});
0 có thực sự là tên của một phương thức được lưu trữ trong
var express = require('express');
var app = express();

var actions = {
  play(data) {
    // ...
  },
  pause(data) {
    // ...
  }
}

app.get('/perform/:action/:payload', function(req, res) {
  let action = actions[req.params.action];
  // BAD: `action` may not be a function
  res.end(action(req.params.payload));
});
1. Ví dụ: nếu
var express = require('express');
var app = express();

var actions = {
  play(data) {
    // ...
  },
  pause(data) {
    // ...
  }
}

app.get('/perform/:action/:payload', function(req, res) {
  let action = actions[req.params.action];
  // BAD: `action` may not be a function
  res.end(action(req.params.payload));
});
0 là
var express = require('express');
var app = express();

var actions = {
  play(data) {
    // ...
  },
  pause(data) {
    // ...
  }
}

app.get('/perform/:action/:payload', function(req, res) {
  let action = actions[req.params.action];
  // BAD: `action` may not be a function
  res.end(action(req.params.payload));
});
8, thì
var express = require('express');
var app = express();

var actions = {
  play(data) {
    // ...
  },
  pause(data) {
    // ...
  }
}

app.get('/perform/:action/:payload', function(req, res) {
  let action = actions[req.params.action];
  // BAD: `action` may not be a function
  res.end(action(req.params.payload));
});
0 sẽ là
var express = require('express');
var app = express();

var actions = new Map();
actions.set("play", function play(data) {
  // ...
});
actions.set("pause", function pause(data) {
  // ...
});

app.get('/perform/:action/:payload', function(req, res) {
  if (actions.has(req.params.action)) {
    if (typeof actions.get(req.params.action) === 'function'){
      let action = actions.get(req.params.action);
    }
    // GOOD: `action` is either the `play` or the `pause` function from above
    res.end(action(req.params.payload));
  } else {
    res.end("Unsupported action.");
  }
});
0 và lệnh gọi sẽ dẫn đến lỗi thời gian chạy

Cách dễ nhất để ngăn chặn điều này là biến

var express = require('express');
var app = express();

var actions = {
  play(data) {
    // ...
  },
  pause(data) {
    // ...
  }
}

app.get('/perform/:action/:payload', function(req, res) {
  let action = actions[req.params.action];
  // BAD: `action` may not be a function
  res.end(action(req.params.payload));
});
1 thành Map và sử dụng
var express = require('express');
var app = express();

var actions = new Map();
actions.set("play", function play(data) {
  // ...
});
actions.set("pause", function pause(data) {
  // ...
});

app.get('/perform/:action/:payload', function(req, res) {
  if (actions.has(req.params.action)) {
    if (typeof actions.get(req.params.action) === 'function'){
      let action = actions.get(req.params.action);
    }
    // GOOD: `action` is either the `play` or the `pause` function from above
    res.end(action(req.params.payload));
  } else {
    res.end("Unsupported action.");
  }
});
3 để kiểm tra xem tên phương thức có hợp lệ hay không trước khi tra cứu.

var express = require('express');
var app = express();

var actions = new Map();
actions.set("play", function play(data) {
  // ...
});
actions.set("pause", function pause(data) {
  // ...
});

app.get('/perform/:action/:payload', function(req, res) {
  if (actions.has(req.params.action)) {
    if (typeof actions.get(req.params.action) === 'function'){
      let action = actions.get(req.params.action);
    }
    // GOOD: `action` is either the `play` or the `pause` function from above
    res.end(action(req.params.payload));
  } else {
    res.end("Unsupported action.");
  }
});

Nếu không thể biến

var express = require('express');
var app = express();

var actions = {
  play(data) {
    // ...
  },
  pause(data) {
    // ...
  }
}

app.get('/perform/:action/:payload', function(req, res) {
  let action = actions[req.params.action];
  // BAD: `action` may not be a function
  res.end(action(req.params.payload));
});
1 thành Map, thì nên thêm dấu kiểm hasOwnProperty để xác thực tên phương thức

Làm cách nào để gọi hàm dựa trên chuỗi trong JavaScript?

Có hai phương pháp để gọi một hàm từ một chuỗi được lưu trữ trong một biến. .
Sử dụng phương pháp đối tượng cửa sổ
Sử dụng phương thức eval()

Làm cách nào để gọi một hàm động trong JavaScript?

function MyClass() { cái này. abc = function() { cảnh báo("abc"); . window['name'] = function() {. }

Làm cách nào để gọi tên hàm trong JavaScript?

Một hàm JavaScript được xác định bằng từ khóa hàm, theo sau là tên, theo sau là dấu ngoặc đơn () . Tên hàm có thể chứa các chữ cái, chữ số, dấu gạch dưới và ký hiệu đô la (quy tắc giống như biến). Dấu ngoặc đơn có thể bao gồm các tên tham số được phân tách bằng dấu phẩy. (tham số1, tham số2,. )

Làm cách nào để gọi một hàm trong vanilla JavaScript?

Gọi hàm bằng tệp JavaScript bên ngoài . Để đưa tệp JavaScript của chúng ta vào tài liệu HTML, chúng ta phải sử dụng thẻ script .