精灵商场项目(十)--前台搭建+JS跨域问题

文章目录

  • 一、精灵前台项目搭建
    • 1.1 整体架构设计
  • 二、构建JL-WEB
    • 2.1 在Idea创建jl-web子工程
      • 2.1.1 pom.xml
      • 2.1.2 application.yml
    • 2.2 修改nginx 实现域名代理
      • 2.2.1 修改nginx配置文件
  • 三、伪静态
    • 3.1 静态页面特点
    • 3.2 搜索引擎工作原理
    • 3.3 伪静态
  • 四、HttpClient(了解)
    • 4.1 导入jar包
    • 4.2 HttpClinet入门案例
    • 4.3 Spring整合HttpClient
      • 4.3.1 配置类和关闭连接配置类
      • 4.3.2 编辑工具API-HttpClientService
      • 4.3.3 get和post测试
  • 五、商品详情展现
    • 5.1 业务调用流程
    • 5.2 HttpClient调用过程
    • 5.2 具体实现步骤
      • 5.2.1 编辑前台的Itemcontroller
      • 5.2.2 编辑前台ItemServiceImpl
      • 5.2.3 编辑后台的WebItemController
      • 5.2.4 编辑ItemService
    • 5.3 商品详情缓存实现
  • 六、JS跨域问题
    • 6.1 HttpClient优化
    • 6.2 同源策略
    • 6.3 跨域实现原理
    • 6.4 JSONP
      • 6.4.1 JSONP方式调用
      • 6.4.2 编辑JS实现跨域访问
      • 6.4.2 API实现JSONP访问
  • 随手笔记
    • 1.view-source是一种协议,查看源码
    • 2.关于数据源异常问题说明
    • 3.关于https报错问题
    • 4.关于redis集群实例化问题
    • 5.关于JSON转化异常问题
      • 5.1 对象如何转化为JSON
      • 5.2 get/set方法不匹配解决方案
    • 6.JSONP 与 cros 解决跨域问题区别
    • 7.Find in Path 全局查找
    • 8.Idea 提示参数

一、精灵前台项目搭建

1.1 整体架构设计

精灵商场项目(十)--前台搭建+JS跨域问题_第1张图片


二、构建JL-WEB

2.1 在Idea创建jl-web子工程

  1. new -> Moudule> maven 创建子项目jl-web
  2. 在pom.xml 里添加 : war
  3. 添加jl-common依赖和跳过测试类打包的插件
  4. 配置application.yml 设置端口为8092,定义springmvc视图解析器
  5. 导入静态资源文件
  6. 修改redis 配置文件 : 将jl-manageredis.properties文件赋值到jl-web中
  7. 设置webapp
  8. 在springBootRun启动类中修改在启动时不要加载数据源配置@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
  9. Run Configurations中添加jl-web的springboot启动项,并将working directory设置为 $MODULE_DIR$

2.1.1 pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>jlartifactId>
        <groupId>com.jlgroupId>
        <version>0.0.1-SNAPSHOTversion>
    parent>
    <modelVersion>4.0.0modelVersion>

    <artifactId>jl-webartifactId>
    <packaging>warpackaging>
    <dependencies>
        <dependency>
            <groupId>com.jlgroupId>
            <artifactId>jl-commonartifactId>
            <version>0.0.1-SNAPSHOTversion>
        dependency>
    dependencies>
    <build>
        <plugins>
            
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-surefire-pluginartifactId>
                <configuration>
                    <skip>trueskip>
                configuration>
            plugin>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>
project>

2.1.2 application.yml

server:
  port: 8092    
spring:     #定义springmvc视图解析器
  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp

2.2 修改nginx 实现域名代理

2.2.1 修改nginx配置文件

修改之后重启nginx

#配置前台服务器
	server {
		listen 80;
		server_name www.jl.com;
		
		location / {
			proxy_pass http://localhost:8092;
		}

	}

2.2.2 修改hosts文件

127.0.0.1 www.jl.com


三、伪静态

3.1 静态页面特点

1.浏览器加载静态资源的速度更快. 浏览器自己有缓存.
2.静态页面更加容易被搜索引擎收录. 百度/谷歌
3.用户的交互性弱.

3.2 搜索引擎工作原理

百度通过 倒排索引的方式实现秒杀级查询

精灵商场项目(十)--前台搭建+JS跨域问题_第2张图片

3.3 伪静态

伪静态技术是指展示出来的是以html一类的静态页面形式,但其实是用ASP一类的动态脚本来处理的,即以html结尾的动态页面

3.4 修改servlet拦截策略

Springboot中默认不拦截为.html结尾的请求.但是根据伪静态的要求,必须拦截以.html为结尾的请求.则需要修改默认的拦截配置

在jl-web中添加该配置

@Configuration	//表示配置类
public class MvcConfigurer implements WebMvcConfigurer{
	//开启匹配后缀型配置
	@Override
	public void configurePathMatch(PathMatchConfigurer configurer) {	
		configurer.setUseSuffixPatternMatch(true);
	}
}

四、HttpClient(了解)

HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包

HttpClient 提供的主要的功能 :

(1)实现了所有 HTTP 的方法(GET,POST,PUT,DELETE 等)

(2)支持自动转向

(3)支持 HTTPS 协议

(4)支持代理服务器等

SpringCloud中服务和服务之间的调用全部是使用HttpClient 传送门

4.1 导入jar包


<dependency>
	<groupId>org.apache.httpcomponentsgroupId>
	<artifactId>httpclientartifactId>
dependency>

4.2 HttpClinet入门案例

1.实例化httpClient对象

2.准备url请求地址 https://www.baidu.com/

3.封装请求方式对象 GET/POST/PUT/DELETE

4.发起http请求.获取服务器响应.

5.判断返回值状态码信息 200.

6.从响应对象中获取服务器返回值数据.

public class TestHttpClient {
	@Test
	public void testGet() throws ClientProtocolException, IOException {
		CloseableHttpClient client = HttpClients.createDefault();
		String url = "https://www.baidu.com";
		HttpGet get = new HttpGet(url);
		CloseableHttpResponse response = client.execute(get);
		if(response.getStatusLine().getStatusCode() == 200) {
			//表示请求服务正确
			HttpEntity entity = response.getEntity();//返回值实体对象
			String result = EntityUtils.toString(entity, "UTF-8");
			System.out.println(result);
		}
	}	
}

4.3 Spring整合HttpClient

4.3.1 配置类和关闭连接配置类

HttpClientConfig.javaHttpClientClose.java

编辑 httpClient.properties

#最大连接数
http.maxTotal = 1000
#并发数
http.defaultMaxPerRoute = 20
#创建连接的最长时间
http.connectTimeout=5000
#从连接池中获取到连接的最长时间
http.connectionRequestTimeout=500
#数据传输的最长时间
http.socketTimeout=5000
#提交请求前测试连接是否可用
http.staleConnectionCheckEnabled=true
package com.jl.web.config;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource(value="classpath:/properties/httpClient.properties")
public class HttpClientConfig {
	@Value("${http.maxTotal}")
	private Integer maxTotal;						//最大连接数

	@Value("${http.defaultMaxPerRoute}")
	private Integer defaultMaxPerRoute;				//最大并发链接数

	@Value("${http.connectTimeout}")
	private Integer connectTimeout;					//创建链接的最大时间

	@Value("${http.connectionRequestTimeout}") 
	private Integer connectionRequestTimeout;		//链接获取超时时间

	@Value("${http.socketTimeout}")
	private Integer socketTimeout;			  		//数据传输最长时间

	@Value("${http.staleConnectionCheckEnabled}")
	private boolean staleConnectionCheckEnabled; 	//提交时检查链接是否可用

	//定义httpClient链接池
	@Bean(name="httpClientConnectionManager")
	public PoolingHttpClientConnectionManager getPoolingHttpClientConnectionManager() {
		PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager();
		manager.setMaxTotal(maxTotal);  //设定最大链接数
		manager.setDefaultMaxPerRoute(defaultMaxPerRoute);  //设定并发链接数
		return manager;
	}

	//定义HttpClient
	/**
	 * 实例化连接池,设置连接池管理器。
	 * 这里需要以参数形式注入上面实例化的连接池管理器
      @Qualifier 指定bean标签进行注入
	 */
	@Bean(name = "httpClientBuilder")
	public HttpClientBuilder getHttpClientBuilder(@Qualifier("httpClientConnectionManager")PoolingHttpClientConnectionManager httpClientConnectionManager){

		//HttpClientBuilder中的构造方法被protected修饰,所以这里不能直接使用new来实例化一个HttpClientBuilder,可以使用HttpClientBuilder提供的静态方法create()来获取HttpClientBuilder对象
		HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
		httpClientBuilder.setConnectionManager(httpClientConnectionManager);
		return httpClientBuilder;
	}

	/**
	 * 	注入连接池,用于获取httpClient
	 * @param httpClientBuilder
	 * @return
	 */
	@Bean
	public CloseableHttpClient getCloseableHttpClient(@Qualifier("httpClientBuilder") HttpClientBuilder httpClientBuilder){

		return httpClientBuilder.build();
	}

	/**
	 * Builder是RequestConfig的一个内部类
	  * 通过RequestConfig的custom方法来获取到一个Builder对象
	  * 设置builder的连接信息
	 * @return
	 */
	@Bean(name = "builder")
	public RequestConfig.Builder getBuilder(){
		RequestConfig.Builder builder = RequestConfig.custom();
		return builder.setConnectTimeout(connectTimeout)
				.setConnectionRequestTimeout(connectionRequestTimeout)
				.setSocketTimeout(socketTimeout)
				.setStaleConnectionCheckEnabled(staleConnectionCheckEnabled);
	}

	/**
	 * 使用builder构建一个RequestConfig对象
	 * @param builder
	 * @return
	 */
	@Bean
	public RequestConfig getRequestConfig(@Qualifier("builder") RequestConfig.Builder builder){
		return builder.build();
	}
}
package com.jl.web.config;

import javax.annotation.PreDestroy;

import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.pool.PoolStats;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component	//交给spring容器管理
public class HttpClientClose extends Thread{
	@Autowired
	private PoolingHttpClientConnectionManager manage;
	private volatile boolean shutdown;	//开关 volatitle表示多线程可变数据,一个线程修改,其他线程立即修改
	
	public HttpClientClose() {
		///System.out.println("执行构造方法,实例化对象");
		//线程开启启动
		this.start();
	}
	
	@Override
	public void run() {
		try {
			//如果服务没有关闭,执行线程
			while(!shutdown) {
				synchronized (this) {
					wait(5000);			//等待5秒
					//System.out.println("线程开始执行,关闭超时链接");
					//关闭超时的链接
					PoolStats stats = manage.getTotalStats();
					int av = stats.getAvailable();	//获取可用的线程数量
					int pend = stats.getPending();	//获取阻塞的线程数量
					int lea = stats.getLeased();    //获取当前正在使用的链接数量
					int max = stats.getMax();
					//System.out.println("max/"+max+":	av/"+av+":  pend/"+pend+":   lea/"+lea);
					manage.closeExpiredConnections();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException();
		}

		super.run();
	}

	//关闭清理无效连接的线程
	@PreDestroy	//容器关闭时执行该方法.
	public void shutdown() {
		shutdown = true;
		synchronized (this) {
			//System.out.println("关闭全部链接!!");
			notifyAll(); //全部从等待中唤醒.执行关闭操作;
		}
	}
}

4.3.2 编辑工具API-HttpClientService

编辑工具API目的简化代码,实现松耦合

作用:帮助用户发起http请求,获取正确的结果返回给用户

参数设计:1.用户url地址 2.Map<参数名,参数值> 3.字符编码

package com.jl.web.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service
public class HttpClientService {
	@Autowired
	private CloseableHttpClient httpClient;
	@Autowired
	private RequestConfig requestConfig;

	public String doGet(String url,Map<String,String> params,String charset){
		String result = null;
		//1.判断字符集编码是否为空 如果为空则给定默认值utf-8
		if(StringUtils.isEmpty(charset)){
			charset = "UTF-8";
		}
		//2.判断用户是否需要传递参数
		if(params != null){
			try {
				URIBuilder uriBuilder = new URIBuilder(url);
				for (Map.Entry<String,String> entry : params.entrySet()) {
					uriBuilder.addParameter(entry.getKey(),entry.getValue());
				}
				//url?id=1&name=tom
				url = uriBuilder.build().toString();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		//3.定义参数提交对象
		HttpGet get = new HttpGet(url);

		//4.为请求设定超时时间
		get.setConfig(requestConfig);

		//5.通过httpClient发送请求
		try {
			CloseableHttpResponse response = httpClient.execute(get);
			if(response.getStatusLine().getStatusCode() == 200){
				//表示程序调用成功
				result = EntityUtils.toString(response.getEntity(),charset);
			}else{
				System.out.println("调用异常:状态信息:"+response.getStatusLine().getStatusCode());
				throw new RuntimeException();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	public String doGet(String url){
		return doGet(url, null, null);
	}

	public String doGet(String url,Map<String,String> params){
		return doGet(url, params, null);
	}

	public String doGet(String url,String charset){
		return doGet(url, null, charset);
	}

	//实现httpClient POST提交
	public String doPost(String url,Map<String,String> params,String charset){
		String result = null;

		//1.定义请求类型
		HttpPost post = new HttpPost(url);
		post.setConfig(requestConfig);  	//定义超时时间

		//2.判断字符集是否为null
		if(StringUtils.isEmpty(charset)){
			charset = "UTF-8";
		}

		//3.判断用户是否传递参数
		if(params !=null){
			//3.2准备List集合信息
			List<NameValuePair> parameters = 
					new ArrayList<>();

			//3.3将数据封装到List集合中
			for (Map.Entry<String,String> entry : params.entrySet()) {

				parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
			}

			//3.1模拟表单提交
			try {
				UrlEncodedFormEntity formEntity = 
						new UrlEncodedFormEntity(parameters,charset); //采用u8编码

				//3.4将实体对象封装到请求对象中
				post.setEntity(formEntity);
			} catch (UnsupportedEncodingException e) {

				e.printStackTrace();
			}
		}

		//4.发送请求
		try {
			CloseableHttpResponse response = 
					httpClient.execute(post);

			//4.1判断返回值状态
			if(response.getStatusLine().getStatusCode() == 200) {

				//4.2表示请求成功
				result = EntityUtils.toString(response.getEntity(),charset);
			}else{
				System.out.println("获取状态码信息:"+response.getStatusLine().getStatusCode());
				throw new RuntimeException();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}


	public String doPost(String url){
		return doPost(url, null, null);
	}

	public String doPost(String url,Map<String,String> params){
		return doPost(url, params, null);
	}

	public String doPost(String url,String charset){
		return doPost(url, null, charset);
	}
}

4.3.3 get和post测试

	@Test
	public void test01() throws ClientProtocolException, IOException{
		CloseableHttpClient httpClient = HttpClients.createDefault();   //创建HTTPClient的实例
		String url = "https://item.jd.com/5236335.html?dist=jd";		//定义访问IP
		HttpPost httpPost = new HttpPost(url); 	//设定请求  
		CloseableHttpResponse response =  httpClient.execute(httpPost);	 //获取response对象
		String html = EntityUtils.toString(response.getEntity());  //获取页面信息
		System.out.println(html);
	}
	
	@Test
	public void testGet() throws ClientProtocolException, IOException{
		//定义httpClient实例
		CloseableHttpClient httpClient = HttpClients.createDefault();
		String uri = "https://item.jd.com/5236335.html?dist=jd";
		HttpGet httpGet = new HttpGet(uri);
		//获取请求的全部参数   GET https://item.jd.com/5236335.html?dist=jd HTTP/1.1
		RequestLine requestLine = httpGet.getRequestLine();
		//获取请求方式     GET/POST
		requestLine.getMethod();
		//获取浏览器  http协议     HTTP/1.1
		requestLine.getProtocolVersion();
		//请求 uri:https://item.jd.com/5236335.html?dist=jd
		requestLine.getUri();
		
		//获取HTTP响应
		CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
		if(httpResponse.getStatusLine().getStatusCode() == 200){
			System.out.println("获取请成功");
			//获取HTML
			String  html = EntityUtils.toString(httpResponse.getEntity());
			System.out.println(html);
		}
	}

五、商品详情展现

5.1 业务调用流程

  1. 用户通过jl-web访问商品信息
  2. jl-web不连接数据库,需要通过jl-manage的服务器获取数据
  3. jl-manage接收到前台web的url请求时,向数据库获取数据
  4. 数据库成功获取数据之后,将数据转化为JSON返回给web.

5.2 HttpClient调用过程

精灵商场项目(十)--前台搭建+JS跨域问题_第3张图片

5.2 具体实现步骤

5.2.1 编辑前台的Itemcontroller

实现商品页面跳转

页面url地址分析 : www.jl.com/items/562379.html

编辑前台的Itemcontroller : 根据商品ID号查询后台商品数据

package com.jl.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.jl.pojo.Item;
import com.jl.pojo.ItemDesc;
import com.jl.service.ItemService;

@Controller	//需要跳转页面.
@RequestMapping("/items")
public class ItemController {
	@Autowired
	private ItemService itemService;
	
	@RequestMapping("/{itemId}")
	public String toItems(@PathVariable Long itemId,Model model) {
		//根据商品ID号查询后台商品数据
		Item item = itemService.findItemById(itemId);
		model.addAttribute("item", item);
		ItemDesc itemDesc = itemService.findItemDescById(itemId);
		model.addAttribute("itemDesc", itemDesc);
		return "item"; //动态的商品展现页面
	}
}

5.2.2 编辑前台ItemServiceImpl

  1. 编辑前台ItemService接口中添加方法

  2. 编辑前台ItemServiceImpl实现

package com.jl.service;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jl.anno.CacheFind;
import com.jl.pojo.Item;
import com.jl.pojo.ItemDesc;
import com.jl.util.HttpClientService;
import com.jl.util.ObjectMapperUtil;

@Service
public class ItemServiceImpl implements ItemService {

	@Autowired
	private HttpClientService httpClient;

	//jl-web服务器
	@Override
	@CacheFind
	public Item findItemById(Long itemId) {
		//连接jl-manage中服务
		String url = "http://manage.jl.com/web/item/findItemById";
		Map<String,String> params = new HashMap<String, String>();
		params.put("itemId", itemId+"");
		String itemJson = httpClient.doGet(url,params);

		return ObjectMapperUtil.toObject(itemJson, Item.class);
	}

	@Override
	@CacheFind
	public ItemDesc findItemDescById(Long itemId) {
		//连接jl-manage中服务
		String url = "http://manage.jl.com/web/item/findItemDescById";
		Map<String,String> params = new HashMap<String, String>();
		params.put("itemId", itemId+"");
		String itemDescJSON = httpClient.doGet(url,params);
		return ObjectMapperUtil.toObject(itemDescJSON,ItemDesc.class);
	}
}

5.2.3 编辑后台的WebItemController

  1. url请求 : http://manage.jl.com/web/item/findItemById?itemId=562379

  2. 编辑后台的WebItemController

  3. 编辑jl-manage获取Item和itemdesc的JSON数据

@RestController
@RequestMapping("/web/item")
public class WebItemController {
	@Autowired
	private ItemService itemService;
    
	@RequestMapping("/findItemById")
	public Item findItemById(Long itemId) {
		return itemService.findItemById(itemId);
	}
    
    //查询商品详情信息
	@RequestMapping("/findItemDescById")
	public ItemDesc findItemDescById(Long itemId) {
		return itemService.findItemDescById(itemId);
	}
}

5.2.4 编辑ItemService

增加findItemById方法,通过mybatis-plus实现

	@Override
	public Item findItemById(Long itemId) {
		return itemMapper.selectById(itemId);
	}

5.3 商品详情缓存实现

在前台的ItemServiceImpl里的 findItemByIdfindItemDescById 方法上加 @CacheFind 注解


六、JS跨域问题

6.1 HttpClient优化

利用浏览器解析JS,发起AJax请求,之后从后台服务器中获取数据

精灵商场项目(十)--前台搭建+JS跨域问题_第4张图片

  1. 域名相同时可以实现访问
  2. 当域名与访问网址域名不同时,发现服务无法正常调用

后面的单点登录系统SSO将使用JSONP来实现跨域问题

6.2 同源策略

浏览规定:如果满足 协议名称://域名:端口号等都相同时表示同域访问

但是如果上述条件中有一项不同.则表示跨域访问.浏览器不予解析返回值.(安全策略)

如下图是同源策略案例

精灵商场项目(十)--前台搭建+JS跨域问题_第5张图片

6.3 跨域实现原理

  1. 利用javaScript中的src属性实现跨域.
  2. 定义回调函数.
  3. 将返回值结果进行特殊格式封装 callback(JSON数据)

传统跨域存在的问题:

  1. 发送跨域请求时利用javaScript中的src属性.这样的操作不通用.
  2. 自己手动定义回调函数.
  3. 返回的数据必须经过回调函数名称封装.但是名称如何保证一致

所以使用JSONP实现跨越

6.4 JSONP

JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。

利用

6.4.1 JSONP方式调用

  1. 可以利用传统ajax实行实现数据请求
  2. 利用js自动生成一个回调函数.并且名称随意,发送请求时自动携带回调函数名称. url?callback="XXXXXXXX"
  3. 动态获取回调函数名称,将数据进行封装 callback(JSON);

6.4.2 编辑JS实现跨域访问

<script type="text/javascript">
        $(function () {
            alert("测试访问开始!!!!!")
            $.ajax({
                url: "http://manage.jl.com/web/testJSONP",
                type: "get",				//jsonp只能支持get请求
                dataType: "jsonp",       //dataType表示返回值类型
                jsonp: "callback",    //指定参数名称
                jsonpCallback: "hello",  //指定回调函数名称
                success: function (data) {   //data经过jQuery封装返回就是json串
                    alert(data.id);
                    alert(data.name);
                }
            });
        })
    script>

6.4.2 API实现JSONP访问

调用JSONPObject(String function, Object value)方法

function为回调函数名称;value 为返回的对象数据

这个API底层实现了 :

1.将对象转换为JSON : String json = ObjectMapperUtil.toJSON(itemDesc);

2.拼接字符串 : callback+"("+json+")"

//利用API实现JSONP跨域访问
	@RequestMapping("/web/testJSONP")
	public JSONPObject testJSONP(String callback) {
		ItemDesc itemDesc = new ItemDesc();
		itemDesc.setItemId(10001L).setItemDesc("商品详情信息!!!!!!");
		return new JSONPObject(callback, itemDesc);
	}

随手笔记

1.view-source是一种协议,查看源码

  • 在浏览器地址栏中输入 view-source:sURL 就可以查看当前网页的源码
  • JS用法 : window.location="view-source:" + window.location

2.关于数据源异常问题说明

异常信息:

精灵商场项目(十)--前台搭建+JS跨域问题_第6张图片

解决方案:

//告知springBoot程序,启动时不要加载数据源配置.
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class SpringBootRun {
	public static void main(String[] args) {
		SpringApplication.run(SpringBootRun.class,args);
	}
}

3.关于https报错问题

说明 : 浏览器默认将http协议转化为https协议.
解决方案:
浏览器输入 : chrome://net-internals/#hsts

输入域名 点击delete 清空缓存 重启谷歌浏览器即可

4.关于redis集群实例化问题

说明:当tomcat服务器启动时,会启动spring容器要求立即注入对象
如果项目中有可能不需要该对象时,可以配置required = false 懒加载

@Autowired(required = false)
private JedisCluster jedis; //连接redis集群

5.关于JSON转化异常问题

5.1 对象如何转化为JSON

说明 : 对象转化JSON数据时,必须调用对象的get方法.
getXXXX()----->去除get前置和()后缀------>XXXXX名称(小写)

说明 : JSON串转化为对象时,调用对象的Set方法
总结:POJO中的get/set方法必须成对出现,则JSON转化正确

5.2 get/set方法不匹配解决方案

说明 : 通过@JsonIgnoreProperties注解实现忽略转化

在pojo类上加入 @JsonIgnoreProperties(ignoreUnknown=true)

表示JSON转化时忽略未知属性

6.JSONP 与 cros 解决跨域问题区别

JSONP 用于get请求,查询功能 ,不能用于post请求,后台使用这个

cros 手机端用的多,可以用于get和post请求,目前用的很少了

目前,前端都用Vue框架,直接调用工具就可以很简单的解决跨越问题

7.Find in Path 全局查找

idea: Ctrl+shift+F

Eclipse : Ctrl+H

8.Idea 提示参数

Ctrl+P

你可能感兴趣的:(分布式电商项目)