当前位置: 首页> 汽车> 报价 > 中国建筑网官网app_web前端就业方向有哪些_查权重网站_品牌推广方式都有哪些

中国建筑网官网app_web前端就业方向有哪些_查权重网站_品牌推广方式都有哪些

时间:2025/7/13 4:33:58来源:https://blog.csdn.net/m0_55049655/article/details/144574670 浏览次数: 0次
中国建筑网官网app_web前端就业方向有哪些_查权重网站_品牌推广方式都有哪些

 1.如何使用JS实现setTimeout功能来模拟setlnterva请写出具体代码

在JavaScript中,setTimeout 和 setInterval 是两个常用的定时器函数,但它们的行为有所不同。setTimeout 用于在指定的延迟后执行一次代码,而 setInterval 则用于每隔指定的时间间隔重复执行代码。

虽然 setInterval 更适合用于需要重复执行的任务,但有时我们可能希望通过 setTimeout 来模拟 setInterval 的行为。这可以通过在 setTimeout 的回调函数中再次调用 setTimeout 来实现。

以下是一个使用 setTimeout 来模拟 setInterval 功能的示例代码:

// 模拟 setInterval 的函数  
function customSetInterval(callback, delay) {  // 定义一个内部函数来递归调用 setTimeout  function repeat() {  // 执行传入的回调函数  callback();  // 在延迟后再次调用 repeat 函数,以模拟 setInterval 的重复执行  setTimeout(repeat, delay);  }  // 首次调用 repeat 函数以启动定时器  setTimeout(repeat, delay);  
}  // 示例用法:每隔 1000 毫秒(1 秒)打印一次消息  
customSetInterval(function() {  console.log('This message is printed every second.');  
}, 1000);

在这个示例中,customSetInterval 函数接受两个参数:一个是要执行的回调函数 callback,另一个是时间间隔 delay(以毫秒为单位)。它内部定义了一个名为 repeat 的函数,该函数会调用传入的回调函数,并使用 setTimeout 来安排自己的下一次执行。这样,repeat 函数就会每隔指定的时间间隔被调用一次,从而模拟了 setInterval 的行为。

需要注意的是,使用 setTimeout 模拟 setInterval 时,由于每次调用 setTimeout 都会有一定的延迟(尽管这个延迟通常非常小),所以实际的时间间隔可能会比指定的值稍微大一些。此外,如果回调函数执行时间过长,也可能会导致下一次调用被延迟。在大多数情况下,这种差异是可以忽略不计的,但在对时间精度要求非常高的场景下,使用 setInterval 可能会更加合适。

防抖节流与setTimeout√setIntervl×

setInterval 和 setTimeout 是 JavaScript 中用于定时执行任务的两个函数,而节流(throttle)和防抖(debounce)是两种优化高频率事件触发场景的技术。尽管它们在某些方面有相似之处,但 setIntervalsetTimeout 与节流、防抖并不是直接对应的。

setInterval 和 setTimeout

  • setInterval:用于每隔固定的时间间隔重复执行某个任务。它无法处理任务执行所需时间超过间隔的情况,这可能导致任务堆积或延迟。
  • setTimeout:用于在指定的延迟后执行一次任务。它更灵活,可以用于创建基于时间的延迟或一次性任务。

节流(Throttle)

节流是一种限制函数执行频率的技术,确保函数在指定的时间间隔内只执行一次。它常用于处理如滚动、窗口大小调整等频繁触发的事件,以防止性能问题。

防抖(Debounce)

防抖是一种限制函数在短时间内被频繁调用的技术。它确保只有在最后一次调用后的一段时间内没有新的调用时,才执行该函数。这常用于处理如输入框输入、按钮点击等事件,以减少不必要的计算或操作。

关系与区别

  • setInterval 与节流:虽然节流可以限制函数执行的频率,但它不是通过简单地重复执行来实现的。节流通常使用定时器(如 setTimeout)来确保在指定的时间间隔内只执行一次任务,但它会根据任务的执行时间和触发事件的频率动态调整。
  • setTimeout 与防抖:防抖的实现确实经常使用 setTimeout 来延迟函数的执行,直到没有新的触发事件为止。然而,防抖不仅仅是一个简单的 setTimeout 调用,它还需要一种机制来取消之前的定时器,并在新的触发事件发生时重新设置它。

因此,虽然 setInterval 和 setTimeout 可以用于实现节流和防抖的效果,但它们本身并不等同于这两种技术。节流和防抖是更高级的函数式编程概念,它们通过更复杂的逻辑来优化事件处理,以减少不必要的计算和资源消耗。

 2.如何使用JS实现一个模板引擎的功能?请写出具体代码

let template = '我是{{name}},年龄{{age}},性别{{sex}}';

let data = { name: '姓名', age: 18 }

render(template, data); // 我是姓名,年龄18,性别undefined

function render(template, data) { //code here }

 要实现一个简单的模板引擎功能,你可以使用正则表达式来查找模板字符串中的占位符(如 {{name}}{{age}} 等),并用提供的数据对象中的相应值来替换它们。以下是一个实现这种功能的 render 函数:

let template = '我是{{name}},年龄{{age}},性别{{sex}}';  
let data = {  name: '姓名',  age: 18  
};  function render(template, data) {  // 使用正则表达式匹配模板中的占位符,如 {{key}}  const regex = /{{([\w]+)}}/g;  // 使用 replace 方法替换匹配到的占位符  return template.replace(regex, (match, key) => {  // 从 data 对象中获取对应的值,如果未定义则返回 ''  return data.hasOwnProperty(key) ? data[key] : '';  });  
}  console.log(render(template, data)); // 输出:我是姓名,年龄18,性别undefined

在这个实现中:

  1. 正则表达式 /{{([\w]+)}}/g 用于匹配模板字符串中的占位符。这里的 [\w]+ 匹配一个或多个字母、数字或下划线,这通常是占位符中的键名。

  2. template.replace(regex, (match, key) => { ... }) 方法用于替换所有匹配的占位符。match 是整个匹配的占位符(如 {{name}}),key 是通过正则表达式捕获组提取的键名(如 namereplace() 方法会对每个匹配项调用回调函数

  3. 在箭头函数中,data.hasOwnProperty(key) ? data[key] : '' 用于检查 data 对象中是否存在该键名,如果存在则返回对应的值,否则返回空字符串 ''

  4. 最后,render 函数返回替换后的模板字符串。

这个简单的模板引擎不支持复杂的逻辑或循环,但它足够用于基本的字符串替换任务。如果你需要更强大的模板引擎功能,可以考虑使用现有的库,如 Handlebars、Mustache 或 EJS。

3.如何使用JS实现一个下划线(gis_jing)驼峰(gisJing)相互转换的函数?请写出具体代码

在 JavaScript 中,你可以编写函数来实现下划线命名法(snake_case)和驼峰命名法(camelCase)之间的相互转换。以下是一个具体的实现,包括两个函数:一个用于将下划线命名法转换为驼峰命名法,另一个用于将驼峰命名法转换为下划线命名法。

// 下划线命名法转换为驼峰命名法  
function snakeToCamel(str) {  return str.replace(/_(\w)/g, function(match, group1) {  return group1.toUpperCase();  });  
}  // 驼峰命名法转换为下划线命名法  
function camelToSnake(str) {  return str.replace(/[A-Z]/g, function(match) {  return '_' + match.toLowerCase();  }).replace(/^_/, ''); // 去除字符串开头的下划线(如果有的话)  
}  // 测试  
let snakeCaseStr = 'this_is_a_test_string';  
let camelCaseStr = 'thisIsATestString';  console.log(snakeToCamel(snakeCaseStr)); // 输出: thisIsATestString  
console.log(camelToSnake(camelCaseStr)); // 输出: this_is_a_test_string

解释

  1. snakeToCamel 函数
    • 使用正则表达式 /_(\w)/g 来匹配下划线及其后面的一个字母。
    • 在回调函数中,将匹配到的字母(group1)转换为大写,并返回。这样就实现了将下划线后面的字母大写,从而转换为驼峰命名法。
  2. camelToSnake 函数
    • 使用正则表达式 /[A-Z]/g 来匹配所有大写字母。
    • 在回调函数中,将匹配到的大写字母转换为小写,并在其前面加上下划线。
    • 使用 .replace(/^_/, '') 来去除字符串开头的下划线(这是因为在转换第一个大写字母时会在前面加上一个不必要的下划线)。

这两个函数可以相互转换下划线命名法和驼峰命名法,适用于变量名、函数名或任何需要这两种命名风格之间转换的场景。

4.如何使用JS实现一个JSON.stringify函数?请写出具体代码

  1. 处理缩进
    • indent 函数用于处理字符串的缩进。如果 space 是数字,则使用指定数量的空格进行缩进;如果 space 是字符串,则使用该字符串进行缩进。
  2. 处理 replacer
    • 如果 replacer 是一个函数,则对每个键值对调用它。
    • 如果 replacer 是一个数组,则只包含数组中指定的键。
  3. 处理不同数据类型
    • null 直接返回 "null"
    • 字符串需要转义特殊字符(如 \"\n\r\t)。
    • 数字和布尔值直接转换为字符串。
    • 数组和对象则递归地调用 customStringify
  4. 递归处理对象和数组
    • 使用 Array.map 处理数组的每个元素。
    • 使用 for...in 循环遍历对象的键,并处理每个键值对。

在 JavaScript 中,实现一个类似于 JSON.stringify 的函数需要递归地遍历对象的属性,并将它们转换为 JSON 格式的字符串。以下是一个简化的 myJSONStringify 函数实现,它支持对象、数组、字符串、数字、布尔值和 null 的转换,但不包括一些高级功能,如处理函数、undefinedSymbol、循环引用或日期对象等。

function simpleStringify(obj) {// 处理基本数据类型(null, 数字, 字符串, 布尔值)if (obj === null) return 'null';if (typeof obj === 'number' || typeof obj === 'string' || typeof obj === 'boolean') {return JSON.stringify(obj); // 这里为了简化,直接使用内置的JSON.stringify来处理基本类型}// 处理数组if (Array.isArray(obj)) {let arrStr = [];for (let i = 0; i < obj.length; i++) {arrStr.push(simpleStringify(obj[i]));}return '[' + arrStr.join(',') + ']';}// 处理对象if (typeof obj === 'object') {let objStr = [];for (let key in obj) {if (obj.hasOwnProperty(key)) {let keyStr = JSON.stringify(key); // 这里为了简化,直接使用内置的JSON.stringify来处理键名let valueStr = simpleStringify(obj[key]);objStr.push(keyStr + ':' + valueStr);}}return '{' + objStr.join(',') + '}';}// 处理其他类型(函数, undefined, Symbol等)throw new TypeError('Converting circular structure to JSON'); // 简化处理,直接抛出错误
}// 测试
console.log(simpleStringify({ name: "John", age: 30, skills: ["JavaScript", "React"] }));

注意

  1. 这个实现没有处理循环引用,如果尝试转换包含循环引用的对象,它会抛出一个 TypeError。在实际应用中,你可能需要实现一个检测循环引用的机制。

  2. 这个实现也没有处理 undefined、函数、Symbol 和其他特殊对象类型。JSON.stringify 会忽略 undefined 值、函数和 Symbol,并且会抛出错误或转换为 null(对于包含这些值的对象)。

  3. replacer 参数的实现是简化的,它只支持函数和数组形式。JSON.stringify 的 replacer 参数更加复杂,可以是一个函数,用于对每个键值对进行过滤或转换,也可以是一个数组,只包含要包含在结果中的属性名。

  4. space 参数用于美化输出,可以是数字(表示缩进的空格数)或字符串(表示缩进的字符串)。这个实现支持这两种形式。

5.如何使用JS实现一个JSON.parser函数?请写出具体代码

在 JavaScript 中,实现一个类似于 JSON.parse 的函数(我们称之为 myJSONParse)是一个相当复杂的任务,因为你需要处理 JSON 字符串中的各种数据类型(对象、数组、字符串、数字、布尔值、null),以及处理嵌套结构和可能的语法错误。然而,为了简化起见,我们可以编写一个基本的解析器,它能够处理一些常见的 JSON 格式。但请注意,这个解析器将不会处理所有可能的 JSON 边缘情况,也不会像原生的 JSON.parse 那样健壮和高效。

以下是一个简化版的 myJSONParse 函数,它能够解析简单的 JSON 对象和数组:

function simpleParse(jsonString) {// 去除可能存在的空白字符jsonString = jsonString.trim();// 处理空字符串和nullif (jsonString === '' || jsonString === 'null') return null;// 处理基本数据类型(数字, 字符串, 布尔值)if (!isNaN(jsonString) && !jsonString.includes(',')) return Number(jsonString);if (jsonString.startsWith('"') && jsonString.endsWith('"')) return jsonString.slice(1, -1);if (jsonString === 'true') return true;if (jsonString === 'false') return false;// 处理数组if (jsonString.startsWith('[') && jsonString.endsWith(']')) {let arrStr = jsonString.slice(1, -1).split(',');let arr = [];for (let i = 0; i < arrStr.length; i++) {arr.push(simpleParse(arrStr[i].trim()));}return arr;}// 处理对象if (jsonString.startsWith('{') && jsonString.endsWith('}')) {let objStr = jsonString.slice(1, -1).split(',');let obj = {};for (let i = 0; i < objStr.length; i++) {let [keyStr, valueStr] = objStr[i].trim().split(':');let key = simpleParse(keyStr.trim().slice(1, -1)); // 提取键名,并去掉引号let value = simpleParse(valueStr.trim());obj[key] = value;}return obj;}// 处理其他情况(抛出错误)throw new SyntaxError('Unexpected token ' + jsonString.charAt(0));
}// 测试
const jsonString = '{"name":"John","age":30,"skills":["JavaScript","React"]}';
console.log(simpleParse(jsonString));

重要提示

  1. 这个 myJSONParse 函数是一个极度简化的版本,它不能正确处理包含转义字符的字符串、嵌套的对象和数组、null 值、以及JSON格式错误的情况。

  2. 在实际应用中,你应该始终使用 JavaScript 内置的 JSON.parse 方法来解析 JSON 字符串,因为它能够处理所有有效的 JSON 格式,并且提供了更好的错误处理和性能。

  3. 如果你需要编写一个自定义的 JSON 解析器(例如,用于学习目的或处理特定格式的 JSON),你应该深入研究 JSON 的语法规则,并编写一个能够正确处理所有边缘情况的解析器。这通常是一个复杂且容易出错的任务,因此不建议在生产环境中使用自定义的解析器。

 6.如何使用JS实现红黄绿三个灯不断交替重复亮灯?请写出具体代码,要求3s亮一次、黄灯2s亮一次、绿灯1s亮一次

<!DOCTYPE html>  
<html lang="en">  
<head>  
<meta charset="UTF-8">  
<meta name="viewport" content="width=device-width, initial-scale=1.0">  
<title>Traffic Light Simulation</title>  
<style>  .light {  width: 50px;  height: 50px;  border-radius: 50%;  margin: 10px;  display: inline-block;  }  #red { background-color: red; }  #yellow { background-color: yellow; }  #green { background-color: green; }  .hidden { display: none; }  
</style>  
</head>  
<body>  <div id="red" class="light"></div>  
<div id="yellow" class="light hidden"></div>  
<div id="green" class="light hidden"></div>  <script>  
function showLight(lightId, duration) {  const light = document.getElementById(lightId);  light.classList.remove('hidden');  // 使用setTimeout在duration毫秒后隐藏当前灯并显示下一个灯  setTimeout(() => {  light.classList.add('hidden');  nextLight(lightId);  }, duration);  
}  function nextLight(currentLightId) {  let nextLightId;  switch (currentLightId) {  case 'red':  nextLightId = 'yellow';  break;  case 'yellow':  nextLightId = 'green';  break;  case 'green':  nextLightId = 'red';  break;  }  // 根据灯的亮起时间显示下一个灯  const durations = {  'red': 3000, // 红灯3秒  'yellow': 2000, // 黄灯2秒  'green': 1000 // 绿灯1秒  };  showLight(nextLightId, durations[nextLightId]);  
}  // 从红灯开始  
nextLight(''); // 这里传入一个空字符串是为了处理首次调用时没有上一个灯的情况  
// 注意:由于nextLight函数内部会处理灯的顺序,所以首次调用时传入任何非灯ID的值都是可以的,  
// 但为了代码清晰,我们传入一个空字符串来表示这是一个特殊的首次调用。  
// 实际上,你也可以直接调用 showLight('red', 3000); 来开始循环。  
</script>  </body>  
</html>
——————————————————————————————————————————————————————————————————————————————————<!DOCTYPE html>  
<html lang="en">  
<head>  
<meta charset="UTF-8">  
<meta name="viewport" content="width=device-width, initial-scale=1.0">  
<title>Traffic Light Simulation</title>  
<style>  /* 样式可以根据需要调整,这里仅作为示例 */  .light {  width: 50px;  height: 50px;  border-radius: 50%;  margin: 10px;  display: inline-block;  opacity: 0; /* 初始时隐藏所有灯 */  transition: opacity 0.5s; /* 添加过渡效果 */  }  #red.active { background-color: red; opacity: 1; }  #yellow.active { background-color: yellow; opacity: 1; }  #green.active { background-color: green; opacity: 1; }  
</style>  
</head>  
<body>  <div id="red" class="light"></div>  
<div id="yellow" class="light"></div>  
<div id="green" class="light"></div>  <script>  
function red() {  console.log('red');  showLight('red', 3000, green);  
}  function green() {  console.log('green');  showLight('green', 1000, yellow);  
}  function yellow() {  console.log('yellow');  showLight('yellow', 2000, red);  
}  function showLight(lightId, duration, nextFunction) {  // 隐藏所有灯  const lights = document.querySelectorAll('.light');  lights.forEach(light => {  light.classList.remove('active');  });  // 显示当前灯  const currentLight = document.getElementById(lightId);  currentLight.classList.add('active');  // 使用setTimeout在延时后调用下一个函数  setTimeout(() => {  nextFunction();  }, duration);  
}  // 从红灯开始循环  
document.addEventListener('DOMContentLoaded', () => {  red();  
});  
</script>  </body>  
</html>

7.如何基于XMLHttpRequest对象实现AJAX请求?请写出具体代码

// 创建一个XMLHttpRequest实例  var xhr = new XMLHttpRequest();  // 配置请求:GET方法,请求的URL  xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true);  // 设置响应类型(可选,默认为空字符串,表示服务器返回什么类型就接受什么类型)  xhr.responseType = 'json'; // 这里我们期望服务器返回JSON格式的数据  // 定义当请求完成并且响应已就绪时要调用的函数  xhr.onload = function() {  if (xhr.status >= 200 && xhr.status < 300) {  // 请求成功,处理响应数据  var responseData = xhr.response; // 由于设置了responseType为'json',这里直接得到JSON对象  console.log(responseData);  // 例如,将响应数据显示在页面上  document.getElementById('responseDiv').innerText = JSON.stringify(responseData, null, 2);  } else {  // 请求失败,处理错误  console.error('The request failed with status ' + xhr.status + ': ' + xhr.statusText);  }  };  // 定义当请求发生错误时要调用的函数(可选,但推荐设置)  xhr.onerror = function() {  console.error('An error occurred during the request.');  };  // 发送请求(对于GET请求,没有请求体,所以这里不需要传递任何数据)  xhr.send();  
————————————————————————————————————————————————————————————————————————————————————————
// 创建一个XMLHttpRequest实例  var xhr = new XMLHttpRequest();  // 配置请求:POST方法,请求的URL  xhr.open('POST', 'https://example.com/api/data', true);  // 设置请求头(如果需要的话,比如设置Content-Type)  xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');  // 定义当请求完成并且响应已就绪时要调用的函数  xhr.onload = function() {  if (xhr.status >= 200 && xhr.status < 300) {  // 请求成功,处理响应数据  var responseData = JSON.parse(xhr.responseText); // 解析服务器返回的JSON响应  console.log(responseData);  // 例如,将响应数据显示在页面上  document.getElementById('responseDiv').innerText = JSON.stringify(responseData, null, 2);  } else {  // 请求失败,处理错误  console.error('The request failed with status ' + xhr.status + ': ' + xhr.statusText);  }  };  // 定义当请求发生错误时要调用的函数(可选,但推荐设置)  xhr.onerror = function() {  console.error('An error occurred during the request.');  };  // 准备要发送的数据(这里将表单数据转换为JSON格式)  var formData = new FormData(document.getElementById('dataForm'));  var postData = {  name: formData.get('name'),  age: formData.get('age')  };  var jsonData = JSON.stringify(postData);  // 发送请求并传递数据  xhr.send(jsonData);  

8.如何使用JS实现基于Promise的AJAX请求封装?请写出具体代码

function ajax(method, url, data = null, headers = {}) {  return new Promise((resolve, reject) => {  // 创建一个XMLHttpRequest实例  const xhr = new XMLHttpRequest();  // 初始化请求  xhr.open(method, url, true);  // 设置请求头(如果需要的话)  for (let key in headers) {  if (headers.hasOwnProperty(key)) {  xhr.setRequestHeader(key, headers[key]);  }  }  // 定义当请求完成并且响应已就绪时要调用的函数  xhr.onload = function() {  // 检查请求是否成功  if (xhr.status >= 200 && xhr.status < 300) {  // 请求成功,解析响应数据并调用resolve  try {  const responseData = JSON.parse(xhr.responseText);  resolve(responseData);  } catch (error) {  // 如果解析JSON失败,则调用reject  reject(new Error('Failed to parse response as JSON'));  }  } else {  // 请求失败,调用reject并传递错误信息  reject(new Error(`Request failed with status ${xhr.status}: ${xhr.statusText}`));  }  };  // 定义当请求发生错误时要调用的函数  xhr.onerror = function() {  // 请求过程中发生错误,调用reject并传递错误信息  reject(new Error('An error occurred during the request.'));  };  // 设置请求体(如果是POST或PUT等需要发送数据的请求)  const contentType = headers['Content-Type'] || 'application/x-www-form-urlencoded';  let requestBody = null;  if (data !== null && contentType.includes('application/json')) {  requestBody = JSON.stringify(data);  } else if (data !== null && contentType.includes('application/x-www-form-urlencoded')) {  requestBody = new URLSearchParams(data).toString();  }  // 发送请求  xhr.send(requestBody);  });  
}  // 使用示例  
ajax('GET', 'https://jsonplaceholder.typicode.com/posts/1')  .then(response => {  console.log('Success:', response);  })  .catch(error => {  console.error('Error:', error);  });  // POST请求示例  
const postData = {  title: 'foo',  body: 'bar',  userId: 1  
};  
const headers = {  'Content-Type': 'application/json'  
};  
ajax('POST', 'https://jsonplaceholder.typicode.com/posts', postData, headers)  .then(response => {  console.log('Post Success:', response);  })  .catch(error => {  console.error('Post Error:', error);  });

9.如何使用JS实现jsonp请求?请写出具体代码

JSONP

JSONP(JSON with Padding)是一种非官方的跨域数据交换协议,它允许网页从不同域名(服务器)请求数据,而不必受到同源策略(Same-Origin Policy)的限制。同源策略是浏览器的一个安全功能,它阻止网页向与其不同源的服务器发送请求或接收响应,以防止恶意网站窃取敏感信息。

JSONP的工作原理是通过在<script>标签的src属性中包含一个URL来动态加载脚本。这个URL通常指向一个返回JSON格式数据的服务器端脚本。但是,由于直接返回JSON数据会导致跨域问题,JSONP通过在响应数据中包裹一个函数调用,来绕过这个限制。

具体来说,JSONP请求包含以下几个步骤:

  1. 客户端定义回调函数:在客户端(通常是浏览器),开发者定义一个全局函数,这个函数将作为回调函数来接收服务器返回的数据。

  2. 发送JSONP请求:客户端通过创建一个<script>标签,并将其src属性设置为包含回调函数名和查询参数的URL,来发起JSONP请求。这个URL指向一个服务器端脚本,该脚本负责处理请求并返回数据。

  3. 服务器端处理请求:服务器端脚本接收到请求后,解析查询参数中的回调函数名,然后将数据作为参数传递给这个函数,并生成一个JavaScript代码片段。这个代码片段调用了客户端定义的回调函数,并将数据作为参数传递给它。

  4. 客户端接收响应:当<script>标签被加载时,它会执行服务器返回的JavaScript代码片段,这导致客户端定义的回调函数被调用,并且服务器返回的数据作为参数传递给了这个函数。

  5. 处理响应数据:在回调函数中,开发者可以访问和处理服务器返回的数据。

需要注意的是,JSONP有几个重要的限制和安全问题:

  • 只能使用GET请求:由于JSONP是通过<script>标签的src属性来发起请求的,因此它只能使用GET方法,而不能使用POST或其他HTTP方法。
  • 全局函数命名冲突:JSONP依赖于全局函数来处理响应数据,这可能导致命名冲突,特别是当页面上有多个JSONP请求时。
  • 安全风险:由于JSONP请求是通过加载脚本的方式来实现的,因此它容易受到XSS(跨站脚本攻击)等安全威胁。如果服务器被恶意攻击者控制,它可能会返回恶意的JavaScript代码,从而危害用户的安全。

因此,在现代Web开发中,JSONP已经被CORS(跨源资源共享)和fetch API等更安全和更灵活的技术所取代。这些技术提供了更好的跨域数据交换解决方案,并且不需要在客户端和服务器端之间进行特殊的约定或处理。

JSONP(JSON with Padding)是一种跨域请求数据的解决方案,它允许网页从另一个域名(服务器)请求数据,而不需要使用CORS(跨源资源共享)或代理服务器。JSONP通过在URL中添加一个回调函数名,并在服务器响应中包含该回调函数的调用来实现。

JSONP 的原理

  1. 同源策略:浏览器的同源策略(Same-Origin Policy)限制了一个源(协议+域名+端口)的文档或脚本如何与另一个源的资源进行交互。这个策略是为了防止恶意网站读取另一个网站的敏感数据。

  2. <script> 标签不受限制:浏览器允许跨域加载 <script> 标签中的资源,这是 JSONP 能够实现跨域请求的基础。

  3. 动态插入 <script> 标签:通过 JavaScript 动态创建一个 <script> 标签,并将其 src 属性设置为一个跨域的 URL,该 URL 返回的响应体是一段 JavaScript 代码。

  4. 回调函数:服务器端返回的 JavaScript 代码通常包含一个函数调用,这个函数是前端页面事先定义好的。通过这种方式,前端可以接收到跨域请求的结果。

JSONP 的使用方法

  1. 前端代码

    首先,在前端定义一个全局的回调函数,用于处理服务器返回的数据。然后,动态创建一个 <script> 标签,并将其 src 属性指向服务器的 URL,同时带上一个回调函数名作为参数。

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JSONP Example</title>
    </head>
    <body>
    <script>
    // 定义一个全局的回调函数
    function handleResponse(data) {
    console.log('Received data:', data);
    }// 动态创建一个 script 标签
    function fetchData() {
    var script = document.createElement('script');
    script.src = 'https://example.com/data?callback=handleResponse';
    document.body.appendChild(script);// 加载完成后移除 script 标签(可选)
    script.onload = function() {
    document.body.removeChild(script);
    };
    }// 调用函数发起请求
    fetchData();
    </script>
    </body>
    </html>
  2. 后端代码(假设服务器使用 Node.js 和 Express):

    服务器端需要返回一段 JavaScript 代码,这段代码会调用前端定义的回调函数,并将数据作为参数传递进去。

    const express = require('express');
    const app = express();app.get('/data', (req, res) => {
    const callback = req.query.callback;
    const data = {
    message: 'Hello, JSONP!',
    timestamp: new Date().toISOString()
    };// 返回 JavaScript 代码
    res.send(`${callback}(${JSON.stringify(data)})`);
    });app.listen(3000, () => {
    console.log('Server is running on port 3000');
    });

一、前端准备
  1. 定义回调函数
    • 在前端页面中,定义一个全局的回调函数,用于处理服务器返回的数据。这个函数将作为参数传递给服务器,并在服务器响应时被调用。
  2. 创建<script>标签
    • 使用JavaScript动态创建一个<script>标签。这个标签的src属性将设置为服务器的URL,同时带上一个回调函数名作为查询参数(如callback=myFunction)。
  3. <script>标签添加到DOM中
    • 将创建的<script>标签添加到页面的<head><body>中。这一步会导致浏览器向服务器发送一个GET请求,请求URL中包含了回调函数的名称。
二、服务器响应
  1. 接收请求并解析查询参数
    • 服务器接收到请求后,解析URL中的查询参数,找到回调函数的名称。
  2. 准备数据
    • 服务器根据请求处理逻辑准备要返回的数据。这些数据通常是JSON格式的。
  3. 生成JavaScript代码
    • 服务器将准备好的数据包裹在回调函数调用的代码中。例如,如果回调函数名是myFunction,数据是{"key":"value"},则生成的JavaScript代码可能是myFunction({"key":"value"})
  4. 返回响应
    • 服务器将生成的JavaScript代码作为响应体返回给前端。
三、前端执行
  1. 接收并执行JavaScript代码
    • <script>标签被添加到DOM中时,浏览器会加载并执行其src属性指向的URL返回的JavaScript代码。在这个例子中,就是执行服务器返回的myFunction({"key":"value"})
  2. 回调函数处理数据
    • 执行的JavaScript代码会调用前端定义的回调函数(在这个例子中是myFunction),并将数据作为参数传递给该函数。这样,前端就可以处理从服务器获取到的数据了。

注意事项

  1. 安全性:JSONP 存在安全隐患,因为服务器返回的 JavaScript 代码会直接在当前页面执行。如果服务器被攻击,攻击者可以返回恶意的 JavaScript 代码,执行任意操作。因此,务必确保请求的是受信任的服务器。

  2. 全局变量污染:回调函数需要定义在全局作用域中,这可能会导致全局变量污染。现代应用通常会避免使用 JSONP,转而使用更安全的 CORS(跨源资源共享)或代理服务器方案。

  3. 兼容性:JSONP 只支持 GET 请求,不支持 POST 等其他 HTTP 方法。

  4. 替代方案:对于现代应用,推荐使用 CORS、Fetch API 或使用代理服务器来解决跨域问题。

总结

JSONP 是一种简单且有效的跨域请求数据的方法,但它存在安全隐患和全局变量污染等问题。在开发现代应用时,建议优先考虑更安全和灵活的跨域解决方案,如 CORS 或代理服务器。

关键字:中国建筑网官网app_web前端就业方向有哪些_查权重网站_品牌推广方式都有哪些

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: