php根据浏览器调用支付_Android通过外部浏览器调用微信H5支付,Android+PHP详解

看了好多关于讲解微信H5支付开发的文章,大多数都是通过微信内部浏览器来调用支付接口(其实就是公众号支付),可能是因为H5支付接口刚开放不久吧。

微信官方体验链接:http://wxpay.wxutil.com/mch/pay/h5.v2.php,请在微信外浏览器打开。

看了上面的体验链接,如果感兴趣,可以接着往下看,希望对你有所帮助。

一、Android端

Android端代码相对来说比较简单一些,我这边直接调用系统浏览器打开H5支付页面Intent intent = new Intent();

intent.setAction("android.intent.action.VIEW");

Uri content_url = Uri.parse(url); //url里面包含了后端需要用到的参数,例如金额,用户ID

intent.setData(content_url);

startActivity(intent);

刚开始考虑过使用webview来加载支付页面,但是调试接口的时候发现一直报如下错误:

AAffA0nNPuCLAAAAAElFTkSuQmCC

微信官方报错示例图

根据微信官方的报错示例可以看出,应该是webview中没有设置referer导致的。于是,我按照说明加上了referer,然鹅,并没有什么卵用,依然报错。我只好放弃使用webview改用系统浏览器。使用系统浏览器的弊端还是挺明显的,客户端和后台传值不好处理(正在看文章的你,如果用webview调用成功了,还请赐教)

二、PHP端

1.获取从Android端传过来的参数

目前我只想到一种方法,就是通过url携带参数给服务端传值,OK,获取方式如下://当前页面的URL地址为:http://www.XXXXX.com/wechatpay/h5Pay.php?money=100&uid=337828932$string = $_SERVER['QUERY_STRING'];//通过$_SERVER['QUERY_STRING']函数获取url地址?后面的值$androidData = convertUrlQuery($string);//将字符串$string转化为数组$money = $androidData['money '];//获取money值 100$uid = $androidData['uid'];//获取用户ID 337828932

上面用到的convertUrlQuery函数代码//将字符串参数变为数组function convertUrlQuery($query){

$queryParts = explode('&', $query);

$params = array();    foreach ($queryParts as $param) {

$item = explode('=', $param);

$params[$item[0]] = $item[1];

}    return $params;

}

2.调用微信统一下单API2.1 具体参数名称以及各参数的用途请查看微信官方文档 统一下单API//配置需要传递给微信的参数

$input = new WxPayUnifiedOrder();

$input->SetBody("xxxx-商品购买");

$input->SetAttach("xxxx");

$input->SetDevice_info("WEB");

$input->SetOut_trade_no(WxPayConfig::MCHID . date("YmdHis").$uid);//把UID加在末尾主要用于识别用户,给对应的用户充值余额

$input->SetTotal_fee($money);

$input->SetTime_start(date("YmdHis"));

$input->SetTime_expire(date("YmdHis", time() + 600));

$input->SetGoods_tag("t");

$input->SetNotify_url("http://www.xxxxx.com/wechatpay/notify.php");//用于接收微信下发的支付结果通知

$input->SetTrade_type("MWEB");

$input->SetOpenid($openId);

$input->SetScene_info("{\"h5_info\": \"h5_info\"{\"type\": \"Wap\",\"wap_url\": \"http://www.xxxxx.com/shop\",\"wap_name\": \"xxx\"}}");2.2 接下来通过$order = WxPayApi::unifiedOrder($input);获取微信返回的参数,unifiedOrder函数具体实现如下/**

*

* 统一下单,WxPayUnifiedOrder中out_trade_no、body、total_fee、trade_type必填

* appid、mchid、spbill_create_ip、nonce_str不需要填入

* @param WxPayUnifiedOrder $inputObj

* @param int $timeOut

* @throws WxPayException

* @return 成功时返回,其他抛异常

*/

public static function unifiedOrder($inputObj, $timeOut = 6)

{

$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";        //检测必填参数

if(!$inputObj->IsOut_trade_noSet()) {            throw new WxPayException("缺少统一支付接口必填参数out_trade_no!");

}else if(!$inputObj->IsBodySet()){            throw new WxPayException("缺少统一支付接口必填参数body!");

}else if(!$inputObj->IsTotal_feeSet()) {            throw new WxPayException("缺少统一支付接口必填参数total_fee!");

}else if(!$inputObj->IsTrade_typeSet()) {            throw new WxPayException("缺少统一支付接口必填参数trade_type!");

}

//异步通知url未设置,则使用配置文件中的url

if(!$inputObj->IsNotify_urlSet()){

$inputObj->SetNotify_url(WxPayConfig::NOTIFY_URL);//异步通知url

}

$inputObj->SetAppid(WxPayConfig::APPID);//公众账号ID

$inputObj->SetMch_id(WxPayConfig::MCHID);//商户号

$inputObj->SetSpbill_create_ip(self::getIp());//终端ip

//$inputObj->SetSpbill_create_ip("1.1.1.1");

$inputObj->SetNonce_str(self::getNonceStr());//随机字符串

//签名

$inputObj->SetSign();

$xml = $inputObj->ToXml();

$startTimeStamp = self::getMillisecond();//请求开始时间

$response = self::postXmlCurl($xml, $url, false, $timeOut);

$result = WxPayResults::Init($response);        self::reportCostTime($url, $startTimeStamp, $result);//上报请求花费时间

return $result;

}2.3 上面代码中需要注意的有以下3点获取客服端的真实IP地址使用REMOTE_ADDR只能获取访问者本地连接中设置的IP。经本人粗略测试,使用UC浏览的时候将无法直接获取真实IP,这是如果把这个IP传过去,微信将会返回 网络环境未能通过安全验证,请稍后再试 的错误

这时可以使用以下方式获取用户真实IP//获取用户真实IP

public static function getIp(){

$ip = '';        if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){

$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];

}elseif(isset($_SERVER['HTTP_CLIENT_IP'])){

$ip = $_SERVER['HTTP_CLIENT_IP'];

}else{

$ip = $_SERVER['REMOTE_ADDR'];

}

$ip_arr = explode(',', $ip);        return $ip_arr[0];

}把参数转换成XML格式在这JSON横行的年代,还使用XML格式传递数据,也许这是微信的高端操作,也许是他们以前的框架就是那样,这我们就不管了。直接上代码/**

* 输出xml字符

* @throws WxPayException

**/

public function ToXml()

{        if(!is_array($this->values)

|| count($this->values) <= 0)

{            throw new WxPayException("数组数据异常!");

}

$xml = "";        foreach ($this->values as $key=>$val)

{            if (is_numeric($val)){

$xml.="".$val."".$key.">";

}else{

$xml.="".$key.">";

}

}

$xml.="";        return $xml;

}签名方法

签名生成的通用步骤如下:

第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。

特别注意以下重要规则:参数名ASCII码从小到大排序(字典序);

如果参数的值为空不参与签名;

参数名区分大小写;

验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。

微信接口可能增加字段,验证签名时必须支持增加的扩展字段

第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。

key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置/**

* 生成签名

* @return 签名

*/

public function MakeSign()

{        //签名步骤一:按字典序排序参数

ksort($this->values);

$string = $this->ToUrlParams();        //签名步骤二:在string后加入KEY

$string = $string . "&key=".WxPayConfig::KEY;        //签名步骤三:MD5加密

$string = md5($string);        //签名步骤四:所有字符转为大写

$result = strtoupper($string);        return $result;

}    /**

* 格式化参数  --格式化成url参数

*/

public function ToUrlParams()

{

$buff = "";        foreach ($this->values as $k => $v)

{            if($k != "sign" && $v != "" && !is_array($v)){

$buff .= $k . "=" . $v . "&";

}

}

$buff = trim($buff, "&");        return $buff;

}2.4 通过返回的mweb_url参数调起微信APPif ($order['mweb_url']) {

$orderId = $input->GetOut_trade_no();

$payUrl = $order['mweb_url']."&redirect_url=http%3A%2F%2Fwww.xxxx.com%2Fwechatpay%2Forderquery.php%3Ftransaction_id%3D".$orderId;

Log::DEBUG($payUrl);        //通过JS打开链接,调起微信APP支付

echo "";

}这里详细解释一下payUrl中redirect_url参数的含义

正常流程用户支付完成后会返回至发起支付的页面,如需返回至指定页面,则可以在MWEB_URL后拼接上redirect_url参数,来指定回调页面。

如,您希望用户支付完成后跳转至https://www.wechatpay.com.cn,则可以做如下处理:

假设您通过统一下单接口获到的MWEB_URL= https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096

则拼接后的地址为MWEB_URL= https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096&redirect_url=https%3A%2F%2Fwww.wechatpay.com.cn

注意:

1.需对redirect_url进行urlencode处理

2.由于设置redirect_url后,回跳指定页面的操作可能发生在:1,微信支付中间页调起微信收银台后超过5秒 2,用户点击“取消支付“或支付完成后点“完成”按钮。因此无法保证页面回跳时,支付流程已结束,所以商户设置的redirect_url地址不能自动执行查单操作,应让用户去点击按钮触发查单操作,而我后面拼接的$orderId就是用于查单操作的参数。回跳页面展示效果可参考下图

AAffA0nNPuCLAAAAAElFTkSuQmCC

回调页面示例图.png

3.处理微信支付结果通知支付完成后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理,并返回应答。

对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。 (通知频率为15/15/30/180/1800/1800/1800/1800/3600,单位:秒)

注意:同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。

推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。

特别提醒:商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致,防止数据泄漏导致出现“假通知”,造成资金损失。

支付回调基础类/**

*

* 回调基础类

* @author widyhu

*

*/class WxPayNotify extends WxPayNotifyReply{    /**

*

* 回调入口

* @param bool $needSign  是否需要签名输出

*/

final public function Handle($needSign = true)

{

$msg = "OK";        //当返回false的时候,表示notify中调用NotifyCallBack回调失败获取签名校验失败,此时直接回复失败

$result = WxpayApi::notify(array($this, 'NotifyCallBack'), $msg);        if($result == false){            $this->SetReturn_code("FAIL");            $this->SetReturn_msg($msg);            $this->ReplyNotify(false);            return;

} else {            //该分支在成功回调到NotifyCallBack方法,处理完成之后流程

$this->SetReturn_code("SUCCESS");            $this->SetReturn_msg("OK");

}        $this->ReplyNotify($needSign);

}

/**

*

* 回调方法入口,子类可重写该方法

* 注意:

* 1、微信回调超时时间为2s,建议用户使用异步处理流程,确认成功之后立刻回复微信服务器

* 2、微信服务器在调用失败或者接到回包为非确认包的时候,会发起重试,需确保你的回调是可以重入

* @param array $data 回调解释出的参数

* @param string $msg 如果回调处理失败,可以将错误信息输出到该方法

* @return true回调出来完成不需要继续回调,false回调处理未完成需要继续回调

*/

public function NotifyProcess($data, &$msg)

{        //TODO 用户基础该类之后需要重写该方法,成功的时候返回true,失败返回false

return true;

}

/**

*

* notify回调方法,该方法中需要赋值需要输出的参数,不可重写

* @param array $data

* @return true回调出来完成不需要继续回调,false回调处理未完成需要继续回调

*/

final public function NotifyCallBack($data)

{

$msg = "OK";

$result = $this->NotifyProcess($data, $msg);

if($result == true){            $this->SetReturn_code("SUCCESS");            $this->SetReturn_msg("OK");

} else {            $this->SetReturn_code("FAIL");            $this->SetReturn_msg($msg);

}        return $result;

}

/**

*

* 回复通知

* @param bool $needSign 是否需要签名输出

*/

final private function ReplyNotify($needSign = true)

{        //如果需要签名

if($needSign == true &&

$this->GetReturn_code($return_code) == "SUCCESS")

{            $this->SetSign();

}

WxpayApi::replyNotify($this->ToXml());

}

}需要注意的是,如果用户只是打开付款界面,而没有执行付款操作的话,是不会触发通知的。

当我们接收到的参数中同时含有return_code,result_code,trade_state并且每个返回值都为SUCCESS的时候,代表用户付款成功if(array_key_exists("return_code", $result)

&& array_key_exists("result_code", $result)

&&array_key_exists("trade_state", $resultData)

&& $resultData["trade_state"] == "SUCCESS"

&& $result["return_code"] == "SUCCESS"

&& $result["result_code"] == "SUCCESS")

{            //这里执行给用户充值余额的操作

}

4.redirect_url回调页面处理

如果在第2.4步骤中MWEB_URL后拼接上了redirect_url参数,用户支付完成后将返回到这个页面。

当用户点击界面的已完成按钮,将触发查单操作

微信查单操作API

查单操作相关代码如下//查询订单

public function Queryorder($transaction_id)

{

$input = new WxPayOrderQuery();

$input->SetTransaction_id($transaction_id);

$result = WxPayApi::orderQuery($input);

Log::DEBUG("query:" . json_encode($result));        if(array_key_exists("return_code", $result)

&& array_key_exists("result_code", $result)

&& $result["return_code"] == "SUCCESS"

&& $result["result_code"] == "SUCCESS")

{            return $result;

}        return false;

}

界面布局以及相关的逻辑处理:if(isset($_REQUEST["out_trade_no"]) && $_REQUEST["out_trade_no"] != ""){

$out_trade_no = $_REQUEST["out_trade_no"];

$input = new WxPayOrderQuery();

$input->SetOut_trade_no($out_trade_no);

Log::DEBUG("out_trade_no".$out_trade_no);//  printf_info(WxPayApi::orderQuery($input));

$result=WxPayApi::orderQuery($input);    if(array_key_exists("return_code", $result)

&& array_key_exists("result_code", $result)

&& array_key_exists("trade_state", $result)

&& $result["trade_state"] == "SUCCESS"

&& $result["return_code"] == "SUCCESS"

&& $result["result_code"] == "SUCCESS"){

$successUrl="success.html";        echo "";

}else{

$failUrl="fail.html";        echo "";

}    exit();

}?>

window.=function () {        var Request=new UrlSearch(); //实例化

document.getElementById("out_trade_no").value=Request.transaction_id;

document.getElementById("transaction_id").style.height = 0;

document.getElementById("out_trade_no").style.height = 0;

document.getElementById("btn").style.height = 0;

$.DialogByZ.Confirm({Title: "", Content: "请确认微信支付是否已完成",FunL:confirmL,FunR:Immediate})

}    ///

function confirmL(){

$.DialogByZ.Close();

document.getElementById('btn').click();

}    function Immediate(){        //location.href="http://sc.chinaz.com/jiaoben/"

window.location.href="nonglegou://data/?state=fail";

}    function UrlSearch()

{        var name,value;        var str=location.href; //取得整个地址栏

var num=str.indexOf("?")

str=str.substr(num+1); //取得所有参数   stringvar.substr(start [, length ]

var arr=str.split("&"); //各个参数放到数组里

for(var i=0;i < arr.length;i++){

num=arr[i].indexOf("=");            if(num>0){

name=arr[i].substring(0,num);

value=arr[i].substr(num+1);

this[name]=value;

}

}

}

三、总结

微信H5支付的整个流程,大概就是这样子,以下是流程图

AAffA0nNPuCLAAAAAElFTkSuQmCC

接口流程图用户在商户侧完成下单,使用微信支付进行支付

由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB

统一下单接口返回支付相关参数给商户后台,如支付跳转url(参数名“mweb_url”),商户通过mweb_url调起微信支付中间页

中间页进行H5权限的校验,安全性检查(此处常见错误请见下文)

如支付成功,商户后台会接收到微信侧的异步通知

用户在微信支付收银台完成支付或取消支付,返回商户页面(默认为返回支付发起页面)

商户在展示页面,引导用户主动发起支付结果的查询

商户后台判断是否接到收微信侧的支付结果通知,如没有,后台调用我们的订单查询接口确认订单状态

展示最终的订单支付结果给用户

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/454789.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

秒杀系统架构分析与实战

0 系列目录 秒杀系统架构 秒杀系统架构分析与实战1 秒杀业务分析 正常电子商务流程 &#xff08;1&#xff09;查询商品&#xff1b;&#xff08;2&#xff09;创建订单&#xff1b;&#xff08;3&#xff09;扣减库存&#xff1b;&#xff08;4&#xff09;更新订单&#xff1…

Docker 精通之常用命令

Docker 精通系列 Docker 精通之入门Docker 精通之微服务Docker 精通之常用命令Docker 精通之 Dockerfile 配置文件路径 /etc/sysconfig/docker docker镜像及容器目录 主目录&#xff1a;/var/lib/docker 容器存放目录&#xff1a;/var/lib/docker/containers/ 镜像存放目…

世界500强面试题(经典)

本书中的问题&#xff0c;是软件业人士在面试时常问的&#xff0c;其中大多数出自微软公司&#xff0c;也有一些来自世界500强公司中的其 他公司。其实道理是相通的&#xff0c;认真领会&#xff0c;加以变通&#xff0c;当你读完全书时&#xff0c;你会发现你已经找到了一块进…

php 获取字符串中的url,php使用正则表达式获取字符串中的URL

今天写一个问答系统上线之后发现有很多人发链接了,由于业务部门要我们过滤掉网站地址了,下面我给大家分享一个提取字符串url地址函数,代码如下:$str 本文实例讲述了php匹配字符串里所有URL地址的方法。http://www.manongjc.com 分享给大家供大家参考;preg_match_all("/htt…

如何提高安卓代码的质量和语法

本文讲的是如何提高安卓代码的质量和语法&#xff0c;在这篇文章中&#xff0c;我会介绍几种不同的方式&#xff0c;让你通过自动化工具提高你的Android代码质量&#xff0c;包括 Checkstyle&#xff0c; Findbugs&#xff0c;PMD&#xff0c; 当然&#xff0c;还有我们最熟悉的…

洛谷 U3357 C2-走楼梯

https://www.luogu.org/problem/show?pidU3357 题目背景 在你成功地解决了上一个问题之后&#xff0c;方方方不禁有些气恼&#xff0c;于是他在楼梯上跳来跳去&#xff0c;想要你求出他跳的方案数。.. 题目描述 方方方站在一个n阶楼梯下面&#xff0c;他每次可以往上跳一步或两…

Liunx 系统调优

Sysctl命令用来配置与显示在/proc/sys目录中的内核参数&#xff0e;如果想使参数长期保存&#xff0c;可以通过编辑/etc/sysctl.conf文件来实现。 命令格式&#xff1a;sysctl [-n] [-e]-w # 临时改变某个指定参数的值&#xff0c;如sysctl -w net.ipv4.ip_forward1-a # 显示…

php多文件上传存储到表,PHP 实现一种多文件上传的方法

搜索热词之前在实现表单中file类型input选择多图片的时候找到一种方式 也许不是最好的但亲测可行且支持ie7以上以及chrome浏览器在表单中使用正常多文件选择multiple属性PHP;">然后使用AjaxFileUpload或其他方式提交将对应命名的file文件 $file[‘image] 转化为 json打…

CentOS7设置自定义开机启动,添加自定义系统服务

Centos 系统服务脚本目录&#xff1a; /usr/lib/systemd/ 有系统&#xff08;system&#xff09;和用户&#xff08;user&#xff09;之分&#xff0c;如需要开机没有登陆情况下就能运行的程序&#xff0c;存在系统服务&#xff08;system&#xff09;里&#xff0c;即&#xf…

成功应聘Intel的真实经历

编者按&#xff1a;INTEL&#xff08;英特尔&#xff09;公司创建于1968年&#xff0c;是全球最大的芯片制造商&#xff0c;Intel研究中心更是汇聚了全球无数的精英&#xff0c;一批年轻人抱着梦想走入了这里&#xff0c;过去我们谈到了太多关于Intel技术与市场方面&#xff0c…

Kotlin学习记录1

参考我的博客&#xff1a;http://www.isedwardtang.com/2017/09/02/kotlin-primer-1/转载于:https://www.cnblogs.com/EdwardTang/p/7476787.html

Keepalived配置文件详解

keepalivedkeepalived是集群管理中保证集群高可用的一个服务软件&#xff0c;其功能类似于heartbeat&#xff0c;用来防止单点故障。keepalived工作原理keepalived是以VRRP&#xff08;Virtual Router Redundancy Protocol&#xff0c;即虚拟路由冗余协议&#xff09;协议为实现…

php高等数学,中国大学《高等数学(四)》期末答案高校邦《PHP语言程序设计》见面课答案...

参考答案如下Conversation 2Pretco-A12.9-10.mp3:9、中国 A) Some shoes are missing. B) Itsdelivery is delayed.C) The order is cancelled. D) Some packages are damaged.10、中国 A) Giving an additional discount. B) Renewing the contract.C) Sending the goods by a…

深入剖析ThreadLocal实现原理以及内存泄漏问题

关于ThreadLocalMap<ThreadLocal, Object>弱引用问题&#xff1a; 当线程没有结束&#xff0c;但是ThreadLocal已经被回收&#xff0c;则可能导致线程中存在ThreadLocalMap<null, Object>的键值对&#xff0c;造成内存泄露。&#xff08;ThreadLocal被回收&#xf…

解读《普通大学应届毕业生如何成功应聘微软》

《普通大学应届毕业生如何成功应聘微软》这篇文章很有实践性&#xff0c;我所要提的&#xff0c;是最后一道面试&#xff0c;也就是唐骏本人对作者的面试&#xff0c;这一轮看似平常的面试大有门道。仔细想想&#xff0c;为什么这些问题由唐骏本人来问&#xff0c;他为什么要这…

grep 命令的 12 个实例

2019独角兽企业重金招聘Python工程师标准>>> 你是否遇到过需要在文件中查找一个特定的字符串或者样式&#xff0c;但是不知道从哪儿开始&#xff1f;那么,就请grep来帮你吧。 grep是每个Linux发行版都预装的一个强有力的文件模式搜索工具。无论何种原因&#xff0c;…

php 怎么从memcache缓存数据中统计某一字段总数,php和memcache统计在线人数的方法...

$mc new Memcache ();// 连接memcache$mc->connect("127.0.0.1", 11211);// 获取 在线用户 IP 和 在线时间数据$online_members $mc->get(online_members);// 如果为空&#xff0c;初始化数据if (!$online_members) {$online_members array();}// 获取用户i…

ubuntu之ufw防火墙

UFW是Ubuntu下的一个主机端的iptables类防火墙配置工具(底层调用iptables来处理)。这个工具的目的是提供给用户一个可以轻松驾驭的界面&#xff0c;就像包集成和动态检测开放的端口一样。虽然功能较简单&#xff0c;但对桌面型应用来说比较实用&#xff0c;基本常用功能都有&am…

background-size在IE8不兼容问题

background-size在IE8及以下浏览器不兼容&#xff1b;要解决的话要用滤镜&#xff1a; filter: progid: DXImageTransform.Microsoft.AlphaImageLoader( src, sizingMethodscale); 注意&#xff1a;此处src的路径必须是绝对路径&#xff0c;相对路径不可以&#xff01; 当写完…

程序员 大牛 面试

水 滴 石 穿 -- 找工作记 -- yurking&#xff08;yurkinggmail.com&#xff09; 一日一钱&#xff0c;千日千钱&#xff0c;绳锯木断&#xff0c;水滴石穿! 这个东西写出来有一段时间了&#xff0c;但是一直没发&#xff0c;想着等有时间了再好好的看一看&#xff0c;改一…