HTTP客户端和基本的跨域问题

本文介绍了HTTP客户端的基本工具,如浏览器和curl,以及在发送HTTP请求时可能出现的跨域问题。当浏览器从不同源发起请求时,由于同源策略会触发跨域限制。解决跨域问题通常有两种方法:服务端设置Access-Control-Allow-Origin头信息,或者在客户端使用JSONP进行请求。文章通过示例详细展示了如何在Node.js环境中设置服务器以允许跨域请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从HTTP客户端说起

  • 1 ) 浏览器
    • General 表示HTTP的首行
    • Response Headers 表示响应内容
    • Request Headers 表示请求内容
  • 2 ) curl工具用于测试,非浏览器工具
    • curl baidu.com
    • curl www.baidu.com
    • curl -v www.baidu.com
  • 3 ) 其他发送http的工具, 如爬虫程序、微信开发工具等
    • 实现了发送HTTP请求报文的工具都属于HTTP客户端

关于跨域请求

1 ) 准备程序

  • server1.js

    const http = require('http');
    const fs = require('fs');
    
    http.createServer((req, res) => {
        console.log('req come: ', req.url);
        const html = fs.readFileSync('test.html', 'utf8');
        // 默认是下面这个writeHead设置,不写也可以
        res.writeHead(200, {
        	'Content-Type': 'text/html'
        });
        res.end(html);
    }).listen(8000, () => {
        console.log('server is running on port 8000');
    });
    
  • server2.js

    const http = require('http');
    
    http.createServer((req, res) => {
        console.log('req come: ', req.url);
        res.end('req come: ' + req.url);
    }).listen(8001, () => {
        console.log('server is running on port 8001');
    });
    
  • test.html模板

    <script>
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://localhost:8001');
    xhr.send();
    </script>
    

2 ) 启动两个程序

  • $ node server1.js
  • $ node server2.js
  • 打开浏览器访问:http://localhost:8000/

3 ) 出现问题

  • 检查页面节点,已经正常加载
  • 浏览器debug后,发现报错了
    Access to XMLHttpRequest at 'http://localhost:8001/' from origin 'http://localhost:8000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
    
  • 这是一个很常见的错误, 跨域问题出现了,通常情况下协议,域名,端口三者不一致就会出现跨域问题
  • 在server2的控制台上可以看见console.log('req come: ', req.url); 仍会执行
  • 这说明浏览器正常发送了,服务器也接收到了(其实也正常响应返回了)
    • 浏览器接收到了响应内容,但是发现请求是不被服务器允许的
    • 因为没有合法的设置Access-Control-Allow-Origin
    • 于是浏览器忽略了响应内容,并报错
    • 所以跨域问题是浏览器的行为和限制

4 ) 问题解决

  • 通常情况下解决这类问题有三种方式
    • 1 ) 服务端处理
    • 2 ) 客户端处理
    • 3 ) 工具代理:如gulp、grunt、webpack、浏览器插件等跨域代理,与HTTP协议无关, 此处不作讨论
  • 4.1 ) 服务端处理
    • 在被请求的服务器server2中设置支持跨域请求头字段: Access-Control-Allow-Origin
    • 其值可以是通配符,也可以是具体的ip或域名
    • 需要注意的是,在server2.js中添加
      // server2.js
      // 在writeHead时候添加跨域支持
      res.writeHead(200, {
          'Access-Control-Allow-Origin': '*'
      });
      
    • 重启server2服务,刷新http://localhost:8000/
    • 发现已经能正常请求
    • 注意在纯node中是不允许设置Access-Control-Allow-Origin为多个值的
    • 如果要允许多个,在程序中判断url,动态添加Access-Control-Allow-Origin头信息
  • 4.2 ) 客户端处理
    • 使用JSONP来请求,修改test.html内容为:
      <script src='http://localhost:8001'></script>
      
    • 去除server2.js中关于Access-Control-Allow-Origin的writeHead配置
    • 重启server2服务
    • 刷新请求:http://localhost:8000/
    • 发现也是能正常访问的
    • 因为浏览器允许script,link,img等标签的跨域访问
    • JSONP实现的原理就是利用这些允许访问的标签访问跨域资源并处理返回的内容
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值